<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>OOFP | Blog</title><description>Object-Oriented Functional Programming ecosystem for TypeScript. Algebraic data types, dependency injection, and type-safe composition.</description><link>https://oofp.pages.dev/</link><language>en</language><item><title>TypeScript Pipe Function: Composing Functions Without the Nesting Hell</title><link>https://oofp.pages.dev/blog/typescript-pipe-compose-function-composition/</link><guid isPermaLink="true">https://oofp.pages.dev/blog/typescript-pipe-compose-function-composition/</guid><description>Stop writing unreadable nested function calls. Learn how pipe, flow, and compose give you clean, type-safe function composition in TypeScript today.

</description><pubDate>Fri, 05 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Look at this code and tell me the order of operations:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uppercase&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;removeSpaces&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;validate&lt;/span&gt;&lt;span&gt;(input))));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You read it left-to-right, but it executes right-to-left. &lt;code dir=&quot;auto&quot;&gt;validate&lt;/code&gt; runs first, then &lt;code dir=&quot;auto&quot;&gt;removeSpaces&lt;/code&gt;, then &lt;code dir=&quot;auto&quot;&gt;trim&lt;/code&gt;, then &lt;code dir=&quot;auto&quot;&gt;uppercase&lt;/code&gt;. The reading order is the opposite of the execution order.&lt;/p&gt;
&lt;p&gt;Now add one more step:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;format&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;uppercase&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;removeSpaces&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;validate&lt;/span&gt;&lt;span&gt;(input)))));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;And another:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;encode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;format&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;uppercase&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;removeSpaces&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;validate&lt;/span&gt;&lt;span&gt;(input))))));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This does not scale. Every new step wraps the entire expression in another function call. The nesting grows. The parentheses pile up. Inserting a step in the middle means counting parentheses. Removing one means the same. And if any of these functions return a wrapper type like &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;Task&lt;/code&gt;, the nesting becomes genuinely painful.&lt;/p&gt;
&lt;p&gt;There is a better way to write this.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;pipe-left-to-right-composition&quot;&gt;pipe: Left-to-Right Composition&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; takes a value as its first argument and passes it through a sequence of functions, left-to-right. Each function receives the return value of the previous one.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(input, validate, removeSpaces, trim, uppercase);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Same operations. Same result. But now the code reads in execution order: start with &lt;code dir=&quot;auto&quot;&gt;input&lt;/code&gt;, validate it, remove spaces, trim it, uppercase it.&lt;/p&gt;
&lt;p&gt;Adding a step is trivial:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(input, validate, removeSpaces, trim, uppercase, encode);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Removing one is just as easy — delete the line. No parenthesis counting. No restructuring.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;type-inference-through-the-chain&quot;&gt;Type inference through the chain&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;TypeScript infers every intermediate type. If &lt;code dir=&quot;auto&quot;&gt;validate&lt;/code&gt; returns &lt;code dir=&quot;auto&quot;&gt;string&lt;/code&gt;, then &lt;code dir=&quot;auto&quot;&gt;removeSpaces&lt;/code&gt; must accept &lt;code dir=&quot;auto&quot;&gt;string&lt;/code&gt;. If you pass a function that doesn’t match, the compiler tells you immediately:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;double&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;exclaim&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; s &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;!&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; s.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// TypeScript infers each step:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;hello&quot;&lt;/span&gt;&lt;span&gt;,        &lt;/span&gt;&lt;span&gt;// string&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;exclaim,        &lt;/span&gt;&lt;span&gt;// (string) =&gt; string&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;len,            &lt;/span&gt;&lt;span&gt;// (string) =&gt; number&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;double,         &lt;/span&gt;&lt;span&gt;// (number) =&gt; number&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// result: number (10)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Swap &lt;code dir=&quot;auto&quot;&gt;double&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;len&lt;/code&gt; and the compiler catches it. The types flow through the pipeline and every mismatch surfaces at compile time.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;vertical-pipelines&quot;&gt;Vertical pipelines&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;When pipelines get longer, write them vertically. This is the idiomatic style in functional TypeScript:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;processInput&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;raw&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;raw,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;parseJSON,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;(validateSchema),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(normalize),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(enrichWithDefaults),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(serialize),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Each line is one step. You can scan the pipeline top-to-bottom and understand the transformation at a glance.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;flow-creating-reusable-pipelines&quot;&gt;flow: Creating Reusable Pipelines&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; takes a value first and executes immediately. Sometimes you don’t have the value yet — you want to define the pipeline and apply it later. That’s &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; takes functions only and returns a new function:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { flow } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/flow&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;process&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flow&lt;/span&gt;&lt;span&gt;(validate, removeSpaces, trim, uppercase);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// process is a function: (input: string) =&gt; string&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;process&lt;/span&gt;&lt;span&gt;(input);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; composes left-to-right, same as &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt;. The difference is when the computation happens: &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; runs now, &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; builds a function for later.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;where-flow-shines&quot;&gt;Where flow shines&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; when you need to pass a transformation as an argument:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { flow } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/flow&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parsePositiveNumber&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Number&lt;/span&gt;&lt;span&gt;(s),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;isNaN&lt;/span&gt;&lt;span&gt;(n) &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Not a number&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(n)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; (n &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(n) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Must be positive&quot;&lt;/span&gt;&lt;span&gt;))),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Use it directly with Array.map&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;results&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;10&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;-3&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;abc&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;42&quot;&lt;/span&gt;&lt;span&gt;].&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(parsePositiveNumber);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// [Right(10), Left(&quot;Must be positive&quot;), Left(&quot;Not a number&quot;), Right(42)]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Because &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; returns a plain function, it integrates with any API that accepts callbacks: &lt;code dir=&quot;auto&quot;&gt;Array.map&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;Array.filter&lt;/code&gt;, event handlers, middleware chains, you name it.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;naming-pipelines&quot;&gt;Naming pipelines&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; encourages giving names to transformations. This is a readability win:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { flow } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/flow&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; M &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/maybe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parseAge&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.fromNullable&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parseInt&lt;/span&gt;&lt;span&gt;(s, &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;iif&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;isNaN&lt;/span&gt;&lt;span&gt;(n) &lt;/span&gt;&lt;span&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;&amp;#x3C;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;150&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;formatCurrency&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cents&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; cents &lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;dollars&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; dollars.&lt;/span&gt;&lt;span&gt;toFixed&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`$${&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Now &lt;code dir=&quot;auto&quot;&gt;parseAge&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;formatCurrency&lt;/code&gt; are self-documenting, reusable, and testable in isolation.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;compose-right-to-left-mathematical-order&quot;&gt;compose: Right-to-Left (Mathematical Order)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;compose&lt;/code&gt; does the same thing as &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt;, but in reverse order. Functions are listed outermost-first, matching mathematical notation where &lt;code dir=&quot;auto&quot;&gt;(f . g)(x) = f(g(x))&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { compose } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/compose&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;process&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt;(uppercase, trim, removeSpaces, validate);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Same result as flow(validate, removeSpaces, trim, uppercase)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Read it right-to-left: validate, then remove spaces, then trim, then uppercase.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { flow } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/flow&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { compose } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/compose&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;exclaim&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; s &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;!&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;upper&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; s.&lt;/span&gt;&lt;span&gt;toUpperCase&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; s.&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// These produce identical functions:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;withFlow&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flow&lt;/span&gt;&lt;span&gt;(trim, upper, exclaim);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;withCompose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt;(exclaim, upper, trim);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;withFlow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  hi  &quot;&lt;/span&gt;&lt;span&gt;);    &lt;/span&gt;&lt;span&gt;// &quot;HI!&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;withCompose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  hi  &quot;&lt;/span&gt;&lt;span&gt;); &lt;/span&gt;&lt;span&gt;// &quot;HI!&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Most TypeScript developers prefer &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; because left-to-right matches how we read code. &lt;code dir=&quot;auto&quot;&gt;compose&lt;/code&gt; exists for those coming from Haskell or category theory who think in terms of &lt;code dir=&quot;auto&quot;&gt;f . g&lt;/code&gt;. Use whichever reads better for your team.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;real-world-examples&quot;&gt;Real-World Examples&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;data-validation-pipeline&quot;&gt;Data validation pipeline&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;items&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Array&lt;/span&gt;&lt;span&gt;&amp;#x3C;{ &lt;/span&gt;&lt;span&gt;price&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;qty&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt; }&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;discount&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validateOrder&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;unknown&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;typeof&lt;/span&gt;&lt;span&gt; data &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;object&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span&gt; data &lt;/span&gt;&lt;span&gt;!==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(data &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Invalid order data&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;calculateTotal&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;order,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;total: order.items.&lt;/span&gt;&lt;span&gt;reduce&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;sum&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; sum &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; item.price &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; item.qty, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;applyDiscount&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;rate&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;order,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;total: order.total &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; rate),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;processOrder&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;rawData&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;unknown&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;rawData,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;validateOrder,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(calculateTotal),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;applyDiscount&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0.1&lt;/span&gt;&lt;span&gt;)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Each step does one thing. The pipeline is the composition. Adding tax calculation is one line: &lt;code dir=&quot;auto&quot;&gt;E.map(applyTax(0.08))&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;async-pipeline-with-taskeither&quot;&gt;Async pipeline with TaskEither&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; TE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task-either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`/api/users/${&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;r&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; r.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;()),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Failed to fetch user: ${&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;[]&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`/api/orders?userId=${&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;r&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; r.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;()),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Failed to fetch orders: ${&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;calculateTotals&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;orders&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;[]) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orders.&lt;/span&gt;&lt;span&gt;reduce&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;sum&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; sum &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; o.total, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;formatReport&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`Total revenue: $${&lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toFixed&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchAndProcess&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt;(user.id)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(calculateTotals),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(formatReport),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code dir=&quot;auto&quot;&gt;fetchUser&lt;/code&gt; fails, &lt;code dir=&quot;auto&quot;&gt;fetchOrders&lt;/code&gt; never runs. The error propagates through the pipeline without any &lt;code dir=&quot;auto&quot;&gt;try-catch&lt;/code&gt; blocks.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;combining-pipe-and-flow&quot;&gt;Combining pipe and flow&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;A common pattern: define small pipelines with &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt;, orchestrate them with &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { flow } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/flow&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parseNumber&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Number&lt;/span&gt;&lt;span&gt;(s),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;isNaN&lt;/span&gt;&lt;span&gt;(n) &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Invalid number&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(n)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ensureRange&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;min&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;max&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;flow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;iif&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; min &lt;/span&gt;&lt;span&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;&amp;#x3C;=&lt;/span&gt;&lt;span&gt; max),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;mapLeft&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`Must be between ${&lt;/span&gt;&lt;span&gt;min&lt;/span&gt;&lt;span&gt;} and ${&lt;/span&gt;&lt;span&gt;max&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;parseNumber&lt;/span&gt;&lt;span&gt;(input),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ensureRange&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;42&quot;&lt;/span&gt;&lt;span&gt;);   &lt;/span&gt;&lt;span&gt;// Right(42)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;-5&quot;&lt;/span&gt;&lt;span&gt;);   &lt;/span&gt;&lt;span&gt;// Left(&quot;Must be between 0 and 100&quot;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;abc&quot;&lt;/span&gt;&lt;span&gt;);  &lt;/span&gt;&lt;span&gt;// Left(&quot;Invalid number&quot;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; creates the building blocks. &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; assembles them.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;pipe-vs-method-chaining&quot;&gt;pipe vs Method Chaining&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;You might be thinking: “This looks like &lt;code dir=&quot;auto&quot;&gt;.then().then()&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;array.map().filter()&lt;/code&gt;.” Method chaining and &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; solve a similar problem, but &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; is more general.&lt;/p&gt;
&lt;p&gt;Method chaining only works with methods defined on a specific class:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Method chaining — only works with Array&apos;s built-in methods&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;filter&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;reduce&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;sum&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; sum &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; n, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;What if you need to call a utility function from another module in the middle of the chain? You can’t. You have to break the chain, assign to a variable, and start a new chain.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; works with any function, from any module:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; L &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/list&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;L&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;filter&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;L&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;L&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;reduce&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, (&lt;/span&gt;&lt;span&gt;sum&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; sum &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; n),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;formatAsUSD,        &lt;/span&gt;&lt;span&gt;// from your utils module&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;addTaxDisclaimer,   &lt;/span&gt;&lt;span&gt;// from another module&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You can mix functions from any source. There’s no class hierarchy. No prototype chain. Just functions in, values out.&lt;/p&gt;
&lt;p&gt;This also makes testing simpler. Each function in the pipeline is a standalone unit that you can test independently. No need to instantiate a class or mock methods.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;tc39-pipeline-operator&quot;&gt;TC39 Pipeline Operator&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;JavaScript has a &lt;a href=&quot;https://github.com/tc39/proposal-pipeline-operator&quot;&gt;stage 2 proposal&lt;/a&gt; for a pipeline operator &lt;code dir=&quot;auto&quot;&gt;|&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Proposed syntax (not yet available)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; input&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;|&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;|&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;removeSpaces&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;|&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;|&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uppercase&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;It solves the same problem &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; solves. But as of 2025, the proposal has been in stage 2 for years. It requires transpilation with experimental Babel plugins. It has gone through multiple syntax revisions. And it offers no type safety beyond what TypeScript already provides.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; from &lt;code dir=&quot;auto&quot;&gt;@oofp/core/pipe&lt;/code&gt; gives you the same ergonomics today:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Works in any TypeScript project with zero configuration.&lt;/li&gt;
&lt;li&gt;Full type inference through the entire chain.&lt;/li&gt;
&lt;li&gt;No experimental flags or transpiler plugins.&lt;/li&gt;
&lt;li&gt;Available right now, not pending committee approval.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the pipeline operator eventually lands in the language, migrating from &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; will be straightforward. Until then, &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; is the practical choice.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;when-to-use-each&quot;&gt;When to Use Each&lt;/h2&gt;&lt;/div&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Utility&lt;/th&gt;&lt;th&gt;Input&lt;/th&gt;&lt;th&gt;Returns&lt;/th&gt;&lt;th&gt;Use when&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;pipe(value, f, g, h)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;A value + functions&lt;/td&gt;&lt;td&gt;The final result&lt;/td&gt;&lt;td&gt;You have a value and want to transform it now&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;flow(f, g, h)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Functions only&lt;/td&gt;&lt;td&gt;A new function&lt;/td&gt;&lt;td&gt;You want a reusable pipeline to apply later&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;compose(h, g, f)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Functions only (reversed)&lt;/td&gt;&lt;td&gt;A new function&lt;/td&gt;&lt;td&gt;You want right-to-left (mathematical) order&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The decision tree is simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Have a value already?&lt;/strong&gt; Use &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Building a reusable transformation?&lt;/strong&gt; Use &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prefer mathematical notation?&lt;/strong&gt; Use &lt;code dir=&quot;auto&quot;&gt;compose&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In practice, you’ll use &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; about 80% of the time, &lt;code dir=&quot;auto&quot;&gt;flow&lt;/code&gt; about 19%, and &lt;code dir=&quot;auto&quot;&gt;compose&lt;/code&gt; rarely. That’s fine. They all have full TypeScript inference, they all compose cleanly, and they all come from &lt;code dir=&quot;auto&quot;&gt;@oofp/core&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Install the core package:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@oofp/core&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Import what you need:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { flow } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/flow&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { compose } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/compose&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;For a deeper look at each utility with more examples and API details, see the &lt;a href=&quot;https://oofp.pages.dev/core/composition/&quot;&gt;Pipe, Flow &amp;#x26; Compose documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Start with &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt;. Replace one nested function call in your codebase. Once the reading order matches the execution order, you won’t want to go back.&lt;/p&gt;</content:encoded><category>typescript</category><category>functional-programming</category><category>composition</category></item><item><title>Understanding Monads in TypeScript: A Practical Guide</title><link>https://oofp.pages.dev/blog/understanding-monads-typescript-practical-guide/</link><guid isPermaLink="true">https://oofp.pages.dev/blog/understanding-monads-typescript-practical-guide/</guid><description>Monads in TypeScript are simpler than you think. You already use them — Promise and Array are monads. Learn the pattern, then apply it with Maybe, Either, Task, and TaskEither from @oofp/core.

</description><pubDate>Sun, 10 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You have read five blog posts about monads. Each one started with category theory, mentioned burritos, and left you more confused than before. Let’s skip all of that.&lt;/p&gt;
&lt;p&gt;Here is the short version: a monad is a container that supports three operations. You already use two monads every day in TypeScript — &lt;code dir=&quot;auto&quot;&gt;Promise&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;Array&lt;/code&gt;. Once you see the pattern, every monad in &lt;code dir=&quot;auto&quot;&gt;@oofp/core&lt;/code&gt; will feel familiar.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-three-operations&quot;&gt;The Three Operations&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Every monad has three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;of(a)&lt;/code&gt;&lt;/strong&gt; — Put a value into the container.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;map(f)&lt;/code&gt;&lt;/strong&gt; — Transform the value inside, keep the container shape.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;chain(f)&lt;/code&gt;&lt;/strong&gt; — Transform the value into a new container, then flatten.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That’s it. If a type supports these three operations and follows a few simple laws, it’s a monad. Let’s see this with types you already know.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;promise--a-monad-you-use-daily&quot;&gt;Promise — a monad you use daily&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// of — wrap a value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// map — transform the inside (then with a plain return)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;doubled&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; p.&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;); &lt;/span&gt;&lt;span&gt;// Promise&amp;#x3C;number&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// chain — transform into a new Promise (then with an async return)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetched&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; p.&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`/api/users/${&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;)); &lt;/span&gt;&lt;span&gt;// Promise&amp;#x3C;Response&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Promise.resolve&lt;/code&gt; is &lt;code dir=&quot;auto&quot;&gt;of&lt;/code&gt;. &lt;code dir=&quot;auto&quot;&gt;.then&lt;/code&gt; acts as both &lt;code dir=&quot;auto&quot;&gt;map&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt; — JavaScript conflates them. When your callback returns a plain value, it’s &lt;code dir=&quot;auto&quot;&gt;map&lt;/code&gt;. When it returns a &lt;code dir=&quot;auto&quot;&gt;Promise&lt;/code&gt;, it’s &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt;. The runtime flattens the nested &lt;code dir=&quot;auto&quot;&gt;Promise&amp;#x3C;Promise&amp;#x3C;T&gt;&gt;&lt;/code&gt; into &lt;code dir=&quot;auto&quot;&gt;Promise&amp;#x3C;T&gt;&lt;/code&gt; automatically.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;array--another-monad-hiding-in-plain-sight&quot;&gt;Array — another monad hiding in plain sight&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// of — wrap a value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;arr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// map — transform each element&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;doubled&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; arr.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;); &lt;/span&gt;&lt;span&gt;// [84]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// chain — transform each element into an array, then flatten&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;expanded&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; arr.&lt;/span&gt;&lt;span&gt;flatMap&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; [x, x &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;]); &lt;/span&gt;&lt;span&gt;// [42, 420]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Array.of&lt;/code&gt; (or just &lt;code dir=&quot;auto&quot;&gt;[value]&lt;/code&gt;) is &lt;code dir=&quot;auto&quot;&gt;of&lt;/code&gt;. &lt;code dir=&quot;auto&quot;&gt;.map&lt;/code&gt; is &lt;code dir=&quot;auto&quot;&gt;map&lt;/code&gt;. &lt;code dir=&quot;auto&quot;&gt;.flatMap&lt;/code&gt; is &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt;. Same pattern, different container.&lt;/p&gt;
&lt;p&gt;The insight is: &lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt; is &lt;code dir=&quot;auto&quot;&gt;map&lt;/code&gt; followed by &lt;code dir=&quot;auto&quot;&gt;flatten&lt;/code&gt;&lt;/strong&gt;. That’s why it’s also called &lt;code dir=&quot;auto&quot;&gt;flatMap&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;bind&lt;/code&gt;. You apply a function that returns a new container, then flatten the nested result.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;maybe-eliminating-null-checks&quot;&gt;Maybe: Eliminating null Checks&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Now that you see the pattern, let’s apply it to a real problem. Consider this code:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;address&lt;/span&gt;&lt;span&gt;?:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;city&lt;/span&gt;&lt;span&gt;?:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;zip&lt;/span&gt;&lt;span&gt;?:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getCityUppercase&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (user &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;UNKNOWN&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;user.address) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;UNKNOWN&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;user.address.city) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;UNKNOWN&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; user.address.city.&lt;/span&gt;&lt;span&gt;toUpperCase&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Three null checks for one value. Optional chaining helps (&lt;code dir=&quot;auto&quot;&gt;user?.address?.city?.toUpperCase() ?? &quot;UNKNOWN&quot;&lt;/code&gt;), but it doesn’t compose. You can’t reuse pieces of this logic, and the fallback value is buried at the end.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Maybe&lt;/code&gt; is a monad that represents a value that might not exist. It has two states: &lt;code dir=&quot;auto&quot;&gt;Just(value)&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;Nothing&lt;/code&gt;. Here’s the same logic:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; M &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/maybe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getCityUppercase&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(user),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(u.address)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(a.city)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;city&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; city.&lt;/span&gt;&lt;span&gt;toUpperCase&lt;/span&gt;&lt;span&gt;()),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrElse&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;UNKNOWN&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Step by step:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;M.fromNullable(user)&lt;/code&gt; — if &lt;code dir=&quot;auto&quot;&gt;user&lt;/code&gt; is &lt;code dir=&quot;auto&quot;&gt;null&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;undefined&lt;/code&gt;, return &lt;code dir=&quot;auto&quot;&gt;Nothing&lt;/code&gt;. Otherwise, &lt;code dir=&quot;auto&quot;&gt;Just(user)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;M.chain(u =&gt; M.fromNullable(u.address))&lt;/code&gt; — if we have a user, try to get the address. If it’s missing, the whole chain becomes &lt;code dir=&quot;auto&quot;&gt;Nothing&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;M.chain(a =&gt; M.fromNullable(a.city))&lt;/code&gt; — same for city.&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;M.map(city =&gt; city.toUpperCase())&lt;/code&gt; — if we still have a value, transform it.&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;M.getOrElse(() =&gt; &quot;UNKNOWN&quot;)&lt;/code&gt; — extract the value, or use the fallback.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The key point: once any step produces &lt;code dir=&quot;auto&quot;&gt;Nothing&lt;/code&gt;, every subsequent &lt;code dir=&quot;auto&quot;&gt;map&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt; is skipped. The &lt;code dir=&quot;auto&quot;&gt;Nothing&lt;/code&gt; propagates automatically. No null checks, no early returns, no exceptions.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;maybe-api-at-a-glance&quot;&gt;Maybe API at a glance&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; M &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/maybe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;just&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;);              &lt;/span&gt;&lt;span&gt;// Just(42)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;nothing&lt;/span&gt;&lt;span&gt;();             &lt;/span&gt;&lt;span&gt;// Nothing&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;);    &lt;/span&gt;&lt;span&gt;// Nothing&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;);      &lt;/span&gt;&lt;span&gt;// Just(42)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Transform&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);    &lt;/span&gt;&lt;span&gt;// Just(42) -&gt; Just(43), Nothing -&gt; Nothing&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;just&lt;/span&gt;&lt;span&gt;(x &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)); &lt;/span&gt;&lt;span&gt;// Just(42) -&gt; Just(43)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Extract&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrElse&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;);   &lt;/span&gt;&lt;span&gt;// Just(42) -&gt; 42, Nothing -&gt; 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.toNullable;            &lt;/span&gt;&lt;span&gt;// Just(42) -&gt; 42, Nothing -&gt; null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;either-errors-as-values&quot;&gt;Either: Errors as Values&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Maybe&lt;/code&gt; tells you if something is missing, but not why. &lt;code dir=&quot;auto&quot;&gt;Either&amp;#x3C;E, A&gt;&lt;/code&gt; fixes that. It has two states: &lt;code dir=&quot;auto&quot;&gt;Right(value)&lt;/code&gt; for success, &lt;code dir=&quot;auto&quot;&gt;Left(error)&lt;/code&gt; for failure. The error type &lt;code dir=&quot;auto&quot;&gt;E&lt;/code&gt; is explicit in the signature.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ValidationError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;field&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validateEmail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ValidationError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;input.&lt;/span&gt;&lt;span&gt;includes&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;@&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;({ field: &lt;/span&gt;&lt;span&gt;&quot;email&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;&quot;Must contain @&quot;&lt;/span&gt;&lt;span&gt; });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(input);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validateAge&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ValidationError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (input &lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; input &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;150&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;({ field: &lt;/span&gt;&lt;span&gt;&quot;age&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;&quot;Out of range&quot;&lt;/span&gt;&lt;span&gt; });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(input);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validateUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;age&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;validateEmail&lt;/span&gt;&lt;span&gt;(data.email),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validateAge&lt;/span&gt;&lt;span&gt;(data.age)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; data),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt; is a monad where &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt; short-circuits on &lt;code dir=&quot;auto&quot;&gt;Left&lt;/code&gt;. If &lt;code dir=&quot;auto&quot;&gt;validateEmail&lt;/code&gt; fails, &lt;code dir=&quot;auto&quot;&gt;validateAge&lt;/code&gt; never runs. The error type is carried through the pipeline, and the compiler knows about it.&lt;/p&gt;
&lt;p&gt;For a deeper look at Either-based error handling, including async operations and recovery patterns, see &lt;a href=&quot;https://oofp.pages.dev/blog/functional-error-handling-typescript/&quot;&gt;Functional Error Handling in TypeScript&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;task-lazy-async&quot;&gt;Task: Lazy Async&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Promise&lt;/code&gt; has a problem: it’s eager. The moment you create one, it starts executing:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// This fires immediately, whether you want it to or not&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/api/users&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You can’t pass a Promise around without triggering its side effect. You can’t compose Promises without running them. This breaks referential transparency — you can’t substitute the expression with its value without changing program behavior.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Task&amp;#x3C;A&gt;&lt;/code&gt; solves this. It’s a lazy Promise:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Task&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;A &lt;code dir=&quot;auto&quot;&gt;Task&lt;/code&gt; is a function that, when called, produces a &lt;code dir=&quot;auto&quot;&gt;Promise&lt;/code&gt;. Nothing executes until you invoke it.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; T &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Define computation — nothing runs yet&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUsers&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/api/users&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(url)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; res.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;()),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; data.users),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Still nothing has happened.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// NOW it runs:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;users&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUsers&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Because &lt;code dir=&quot;auto&quot;&gt;Task&lt;/code&gt; is just a function, you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pass it around without triggering side effects.&lt;/li&gt;
&lt;li&gt;Compose multiple Tasks into pipelines before executing any of them.&lt;/li&gt;
&lt;li&gt;Retry, delay, or conditionally run Tasks based on other values.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h3 id=&quot;task-api-at-a-glance&quot;&gt;Task API at a glance&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; T &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;);                &lt;/span&gt;&lt;span&gt;// Task that resolves to 42&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);    &lt;/span&gt;&lt;span&gt;// Transform the resolved value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(x &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)); &lt;/span&gt;&lt;span&gt;// Sequence into a new Task&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;);           &lt;/span&gt;&lt;span&gt;// Wait 1 second before resolving&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;taskeither-the-workhorse&quot;&gt;TaskEither: The Workhorse&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;In real applications, most operations are both async and fallible. &lt;code dir=&quot;auto&quot;&gt;TaskEither&amp;#x3C;E, A&gt;&lt;/code&gt; combines both:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;It’s a lazy function that returns a &lt;code dir=&quot;auto&quot;&gt;Promise&lt;/code&gt; which &lt;strong&gt;always resolves&lt;/strong&gt; to an &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt;. No rejections, no unhandled promise errors — just typed success or typed failure.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; TE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task-either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ApiError&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ApiError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`/api/users/${&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;res.ok) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; { status: res.status, message: res.statusText };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; res.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ApiError&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ApiError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;[]&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`/api/orders?user=${&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;res.ok) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; { status: res.status, message: res.statusText };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; res.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;[]&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ApiError&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Compose a complete workflow&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserDashboard&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt;(userId),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt;(user.id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;orders&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orders,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;totalSpent: orders.&lt;/span&gt;&lt;span&gt;reduce&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;sum&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; sum &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; o.total, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Nothing has executed. Run it:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserDashboard&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user-123&quot;&lt;/span&gt;&lt;span&gt;)();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;tryCatch&lt;/code&gt; takes a function that returns a Promise (which might reject) and wraps it into a &lt;code dir=&quot;auto&quot;&gt;TaskEither&lt;/code&gt; that never rejects. The second argument maps the caught error into your typed error.&lt;/p&gt;
&lt;p&gt;This is the monad you will use most in production TypeScript. For retry strategies, error recovery with &lt;code dir=&quot;auto&quot;&gt;orElse&lt;/code&gt;, and concurrent execution with &lt;code dir=&quot;auto&quot;&gt;concurrencyObject&lt;/code&gt;, see the &lt;a href=&quot;https://oofp.pages.dev/blog/functional-error-handling-typescript/&quot;&gt;error handling guide&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-chain-pattern&quot;&gt;The chain Pattern&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Here is the key insight that ties everything together. &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt; is what makes monads powerful. It’s sequential composition where each step can change the container’s state:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;Maybe.chain&lt;/code&gt;&lt;/strong&gt; — a &lt;code dir=&quot;auto&quot;&gt;Just&lt;/code&gt; can become a &lt;code dir=&quot;auto&quot;&gt;Nothing&lt;/code&gt;. Once it’s &lt;code dir=&quot;auto&quot;&gt;Nothing&lt;/code&gt;, the rest is skipped.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;Either.chain&lt;/code&gt;&lt;/strong&gt; — a &lt;code dir=&quot;auto&quot;&gt;Right&lt;/code&gt; can become a &lt;code dir=&quot;auto&quot;&gt;Left&lt;/code&gt;. The error propagates, the rest is skipped.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;Task.chain&lt;/code&gt;&lt;/strong&gt; — one async operation feeds its result into the next. Sequential by construction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;TaskEither.chain&lt;/code&gt;&lt;/strong&gt; — sequences async operations that can fail. If one step produces a &lt;code dir=&quot;auto&quot;&gt;Left&lt;/code&gt;, subsequent steps are skipped.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every monad follows this same structure. Learn &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt; once, and you can use any monad.&lt;/p&gt;
&lt;p&gt;Here’s a practical example that flows through multiple monads:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; M &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/maybe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; TE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task-either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Parse config from environment (sync, might be missing)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Record&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;undefined&lt;/span&gt;&lt;span&gt;&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(env.&lt;/span&gt;&lt;span&gt;API_URL&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(env.&lt;/span&gt;&lt;span&gt;API_KEY&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ url, key })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Validate the config (sync, might fail with reason)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validateConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;config.url.&lt;/span&gt;&lt;span&gt;startsWith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;https&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(config)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;API_URL must use HTTPS&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;c.key.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(c) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;API_KEY too short&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Fetch data using validated config (async, might fail)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchData&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(config.url, {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;headers: { Authorization: &lt;/span&gt;&lt;span&gt;`Bearer ${&lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;r&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; r.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;()),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`Fetch failed: ${&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Three different monads, three different concerns (missing values, validation errors, async failures), but the same &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt; pattern throughout. Each function is small, testable, and composable.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;pipe-gluing-it-together&quot;&gt;pipe: Gluing It Together&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;You might have noticed that every example uses &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt;. Without it, monadic code becomes deeply nested:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Without pipe — nested and hard to read&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrElse&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;UNKNOWN&quot;&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;city&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; city.&lt;/span&gt;&lt;span&gt;toUpperCase&lt;/span&gt;&lt;span&gt;())(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;city&lt;/span&gt;&lt;span&gt;?:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(a.city))(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(u.address))(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(user)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;With &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt;, the same logic reads top to bottom, left to right:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// With pipe — linear and clear&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(user),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(u.address)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(a.city)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;city&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; city.&lt;/span&gt;&lt;span&gt;toUpperCase&lt;/span&gt;&lt;span&gt;()),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;M&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrElse&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;UNKNOWN&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt; takes an initial value and passes it through a chain of functions. Each function receives the output of the previous one. It’s the backbone of compositional code in &lt;code dir=&quot;auto&quot;&gt;@oofp/core&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// pipe(value, f1, f2, f3) === f3(f2(f1(value)))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;,    &lt;/span&gt;&lt;span&gt;// 10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,    &lt;/span&gt;&lt;span&gt;// 11&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`${&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;}!`&lt;/span&gt;&lt;span&gt;,  &lt;/span&gt;&lt;span&gt;// &quot;11!&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;when-to-use-what&quot;&gt;When to Use What&lt;/h2&gt;&lt;/div&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Situation&lt;/th&gt;&lt;th&gt;Monad&lt;/th&gt;&lt;th&gt;Why&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Value might not exist&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;Maybe&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Eliminates null checks, propagates absence&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Operation can fail (sync)&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Typed errors in the function signature&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Async operation&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;Task&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Lazy, composable, referentially transparent&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Async + can fail&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;TaskEither&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Production workhorse for real-world apps&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Needs runtime context&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;Reader&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Dependency injection without globals&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Async + fail + context&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;ReaderTaskEither&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Full-stack application architecture&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Start with &lt;code dir=&quot;auto&quot;&gt;Maybe&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt; for synchronous code. Move to &lt;code dir=&quot;auto&quot;&gt;TaskEither&lt;/code&gt; when you need async operations with typed errors. Reach for &lt;code dir=&quot;auto&quot;&gt;ReaderTaskEither&lt;/code&gt; when you need to thread configuration, database connections, or other context through your application.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Install &lt;code dir=&quot;auto&quot;&gt;@oofp/core&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@oofp/core&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Import what you need:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; M &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/maybe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; T &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; TE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task-either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Explore each module in the documentation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/maybe/&quot;&gt;Maybe&lt;/a&gt; — optional values without null&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/either/&quot;&gt;Either&lt;/a&gt; — synchronous error handling&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/task/&quot;&gt;Task&lt;/a&gt; — lazy async computation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/task-either/&quot;&gt;TaskEither&lt;/a&gt; — async error handling&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/composition/&quot;&gt;Pipe, Flow &amp;#x26; Compose&lt;/a&gt; — function composition&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The pattern is always the same: wrap a value in a container, transform it with &lt;code dir=&quot;auto&quot;&gt;map&lt;/code&gt;, sequence operations with &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt;, and extract the result at the boundary. Once you internalize this, every monad is just a variation on the same theme.&lt;/p&gt;</content:encoded><category>typescript</category><category>functional-programming</category><category>monads</category></item><item><title>Dependency Injection in TypeScript Without Classes or Decorators</title><link>https://oofp.pages.dev/blog/dependency-injection-typescript-reader-pattern/</link><guid isPermaLink="true">https://oofp.pages.dev/blog/dependency-injection-typescript-reader-pattern/</guid><description>Stop fighting IoC containers. The Reader pattern gives you compile-time dependency injection in TypeScript using plain functions and types — no decorators, no reflect-metadata, no runtime overhead.

</description><pubDate>Sun, 20 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You want dependency injection in TypeScript. So you reach for InversifyJS, tsyringe, or NestJS. You add &lt;code dir=&quot;auto&quot;&gt;reflect-metadata&lt;/code&gt; to your entry point. You slap &lt;code dir=&quot;auto&quot;&gt;@Injectable()&lt;/code&gt; on every class. You register bindings in a container. You configure modules. You emit decorator metadata. You lose tree-shaking. And after all that setup, the compiler still cannot tell you if you forgot to register a dependency — you find out at runtime.&lt;/p&gt;
&lt;p&gt;There is a simpler way. One that uses the type system itself as the DI container.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-class-based-di-tax&quot;&gt;The Class-Based DI Tax&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Here is what dependency injection looks like in most TypeScript projects:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { injectable, inject } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;tsyringe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;injectable&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserRepository&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;constructor&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;inject&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Database&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;db&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Database&lt;/span&gt;&lt;span&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;findById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.db.&lt;/span&gt;&lt;span&gt;query&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;SELECT * FROM users WHERE id = ?&quot;&lt;/span&gt;&lt;span&gt;, [id]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;injectable&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;constructor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;inject&lt;/span&gt;&lt;span&gt;(UserRepository) &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userRepo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserRepository&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;inject&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Logger&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;logger&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Logger&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.logger.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Fetching user ${&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.userRepo.&lt;/span&gt;&lt;span&gt;findById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;user) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;User not found&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; user;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Somewhere in bootstrap code...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;container.&lt;/span&gt;&lt;span&gt;register&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Database&quot;&lt;/span&gt;&lt;span&gt;, { useClass: PostgresDatabase });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;container.&lt;/span&gt;&lt;span&gt;register&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Logger&quot;&lt;/span&gt;&lt;span&gt;, { useClass: ConsoleLogger });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;service&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; container.&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;(UserService);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This works. But count the costs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Runtime reflection.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;reflect-metadata&lt;/code&gt; must be imported before anything else. Decorator metadata is emitted into JavaScript output, adding bundle weight.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;String tokens.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;@inject(&quot;Database&quot;)&lt;/code&gt; is a string. Rename it and nothing warns you. Forget to register it and you get a runtime error.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No tree-shaking.&lt;/strong&gt; The container holds references to everything. Bundlers cannot eliminate unused code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Class coupling.&lt;/strong&gt; Every service must be a class. Every dependency must go through the constructor. You cannot use plain functions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing ceremony.&lt;/strong&gt; To test &lt;code dir=&quot;auto&quot;&gt;UserService&lt;/code&gt;, you create a testing module, override providers, resolve from a test container. That is a lot of machinery for calling a function with a mock.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What if the type system could do all of this at compile time, with zero runtime overhead?&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-reader-pattern&quot;&gt;The Reader Pattern&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;A &lt;code dir=&quot;auto&quot;&gt;Reader&amp;#x3C;R, A&gt;&lt;/code&gt; is a function:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Reader&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;R&lt;/code&gt; is what the function &lt;em&gt;needs&lt;/em&gt;. &lt;code dir=&quot;auto&quot;&gt;A&lt;/code&gt; is what it &lt;em&gt;produces&lt;/em&gt;. The dependency requirements are encoded in the type signature, not in decorators or a container registry.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; R &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/reader&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Config&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;apiUrl&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getApiUrl&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Reader&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Config&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ctx.apiUrl);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;buildHeaders&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;getApiUrl,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ &lt;/span&gt;&lt;span&gt;&quot;X-Api-Base&quot;&lt;/span&gt;&lt;span&gt;: url })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Provide the context at the boundary&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headers&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;({ apiUrl: &lt;/span&gt;&lt;span&gt;&quot;https://api.example.com&quot;&lt;/span&gt;&lt;span&gt;, timeout: &lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt; })(buildHeaders);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// { &quot;X-Api-Base&quot;: &quot;https://api.example.com&quot; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;ask()&lt;/code&gt; gives you the entire context:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;program&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ask&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Config&lt;/span&gt;&lt;span&gt;&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`Connecting to ${&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;apiUrl&lt;/span&gt;&lt;span&gt;} with timeout ${&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;}ms`&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt; lets you sequence computations that share the same context:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Reader&lt;/span&gt;&lt;span&gt;&amp;#x3C;{ &lt;/span&gt;&lt;span&gt;userRepo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserRepo&lt;/span&gt;&lt;span&gt; }, &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt;(({ &lt;/span&gt;&lt;span&gt;userRepo&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; userRepo.&lt;/span&gt;&lt;span&gt;findById&lt;/span&gt;&lt;span&gt;(id));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;logResult&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Reader&lt;/span&gt;&lt;span&gt;&amp;#x3C;{ &lt;/span&gt;&lt;span&gt;logger&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Logger&lt;/span&gt;&lt;span&gt; }, &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt;(({ &lt;/span&gt;&lt;span&gt;logger&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; user &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`Found: ${&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Not found&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;logger.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(msg);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; msg;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code dir=&quot;auto&quot;&gt;chainw&lt;/code&gt; to merge contexts from different modules:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;findAndLog&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;getUser&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chainw&lt;/span&gt;&lt;span&gt;(logResult),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Reader&amp;#x3C;{ userRepo: UserRepo } &amp;#x26; { logger: Logger }, string&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;TypeScript infers the combined requirement. No registration step.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;readertaskeither-for-real-applications&quot;&gt;ReaderTaskEither for Real Applications&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Reader&lt;/code&gt; handles dependency injection. But real application code is async and can fail. &lt;code dir=&quot;auto&quot;&gt;ReaderTaskEither&amp;#x3C;R, E, A&gt;&lt;/code&gt; combines all three:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ReaderTaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;r&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;R&lt;/code&gt; — dependencies the computation requires&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;E&lt;/code&gt; — typed error on failure&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;A&lt;/code&gt; — success value&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nothing executes until you provide the context and call the resulting thunk. The entire pipeline is a description, not an execution.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; RTE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/reader-task-either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; TE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task-either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Define what your functions need via types&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Database&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;db&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;findUser&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;&gt; } };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Logger&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;logger&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; } };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;code&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Each function declares its dependencies in the R type parameter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;findUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ReaderTaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Database&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ask&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Database&lt;/span&gt;&lt;span&gt;&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chaint&lt;/span&gt;&lt;span&gt;(({ &lt;/span&gt;&lt;span&gt;db&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; db.&lt;/span&gt;&lt;span&gt;findUser&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ code: &lt;/span&gt;&lt;span&gt;&quot;DB_ERROR&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;(err) })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt;&gt;({ code: &lt;/span&gt;&lt;span&gt;&quot;NOT_FOUND&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;&quot;User not found&quot;&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(user),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;logAction&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ReaderTaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Logger&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;never&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ask&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Logger&lt;/span&gt;&lt;span&gt;&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(({ &lt;/span&gt;&lt;span&gt;logger&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; logger.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(msg)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Look at &lt;code dir=&quot;auto&quot;&gt;findUser&lt;/code&gt;. Its type signature says: “Give me a &lt;code dir=&quot;auto&quot;&gt;Database&lt;/code&gt; in the context, and I will asynchronously return either an &lt;code dir=&quot;auto&quot;&gt;AppError&lt;/code&gt; or a &lt;code dir=&quot;auto&quot;&gt;User&lt;/code&gt;.” That is the entire dependency injection contract, enforced by the compiler.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;composing-services&quot;&gt;Composing Services&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The key insight is what happens when you chain functions that need &lt;em&gt;different&lt;/em&gt; contexts. &lt;code dir=&quot;auto&quot;&gt;chainwc&lt;/code&gt; (chain with context widening) merges them automatically:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;orderRepo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;findByUserId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;[]&gt; } };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserOrders&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ReaderTaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;[]&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ask&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt;&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chaint&lt;/span&gt;&lt;span&gt;(({ &lt;/span&gt;&lt;span&gt;orderRepo&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; orderRepo.&lt;/span&gt;&lt;span&gt;findByUserId&lt;/span&gt;&lt;span&gt;(userId),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ code: &lt;/span&gt;&lt;span&gt;&quot;DB_ERROR&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;(err) })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Compose operations from different modules&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserWithOrders&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;findUser&lt;/span&gt;&lt;span&gt;(id),                                &lt;/span&gt;&lt;span&gt;// RTE&amp;#x3C;Database, AppError, User&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chainwc&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;span&gt;// merges Database &amp;#x26; OrderService &amp;#x26; Logger&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;logAction&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Fetching orders for ${&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chainwc&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserOrders&lt;/span&gt;&lt;span&gt;(user.id)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;orders&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ user, orders })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Final type: RTE&amp;#x3C;Database &amp;#x26; OrderService &amp;#x26; Logger, AppError, { user: User; orders: Order[] }&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;TypeScript computed the intersection &lt;code dir=&quot;auto&quot;&gt;Database &amp;#x26; OrderService &amp;#x26; Logger&lt;/code&gt; from the composition. You did not write it. You did not register it. The compiler inferred it from how you composed your functions.&lt;/p&gt;
&lt;p&gt;This is compile-time dependency injection. If you forget to provide &lt;code dir=&quot;auto&quot;&gt;orderRepo&lt;/code&gt; when you run this pipeline, the compiler rejects it. Not at runtime — at build time.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;providing-dependencies&quot;&gt;Providing Dependencies&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;RTE.provide&lt;/code&gt; satisfies part of the context, removing those keys from the type:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;program&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserWithOrders&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;123&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// RTE&amp;#x3C;Database &amp;#x26; OrderService &amp;#x26; Logger, AppError, { user: User; orders: Order[] }&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;withLogger&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;program,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provide&lt;/span&gt;&lt;span&gt;({ logger: { info: console.log } }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// RTE&amp;#x3C;Database &amp;#x26; OrderService, AppError, { user: User; orders: Order[] }&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;withDb&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;withLogger,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provide&lt;/span&gt;&lt;span&gt;({ db: &lt;/span&gt;&lt;span&gt;createDb&lt;/span&gt;&lt;span&gt;() }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// RTE&amp;#x3C;OrderService, AppError, { user: User; orders: Order[] }&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fullyProvided&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;withDb,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provide&lt;/span&gt;&lt;span&gt;({ orderRepo: &lt;/span&gt;&lt;span&gt;createOrderRepo&lt;/span&gt;&lt;span&gt;() }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// RTE&amp;#x3C;{}, AppError, { user: User; orders: Order[] }&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Each &lt;code dir=&quot;auto&quot;&gt;provide&lt;/code&gt; call narrows the &lt;code dir=&quot;auto&quot;&gt;R&lt;/code&gt; type. When &lt;code dir=&quot;auto&quot;&gt;R&lt;/code&gt; reaches &lt;code dir=&quot;auto&quot;&gt;{}&lt;/code&gt;, all dependencies are satisfied and you can run the pipeline.&lt;/p&gt;
&lt;p&gt;For async dependency creation, use &lt;code dir=&quot;auto&quot;&gt;provideTE&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createDbPool&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Database&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; Pool.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;({ host: &lt;/span&gt;&lt;span&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span&gt;, max: &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt; }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ code: &lt;/span&gt;&lt;span&gt;&quot;POOL_ERROR&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;(err) })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;pool&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ db: { &lt;/span&gt;&lt;span&gt;findUser&lt;/span&gt;&lt;span&gt;: (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; pool.&lt;/span&gt;&lt;span&gt;query&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;SELECT ...&quot;&lt;/span&gt;&lt;span&gt;) } })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;withDb&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;program,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provideTE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;createDbPool&lt;/span&gt;&lt;span&gt;()),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;When a dependency itself depends on another part of the context, use &lt;code dir=&quot;auto&quot;&gt;provideRTE&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Config&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;dbConnectionString&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; } };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;withDbFromConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;program,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provideRTE&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Config&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(ctx),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chaint&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; Pool.&lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt;(c.config.dbConnectionString),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AppError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ code: &lt;/span&gt;&lt;span&gt;&quot;POOL_ERROR&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;(err) })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;pool&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ db: pool })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Database is provided, but Config is now required&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;running-at-the-boundary&quot;&gt;Running at the Boundary&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;At the edge of your application — an HTTP handler, a CLI command, a test — you provide the full context and execute:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;app.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/users/:id/orders&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;req&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;getUserWithOrders&lt;/span&gt;&lt;span&gt;(req.params.id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;db: appDb,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderRepo: appOrderRepo,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;logger: appLogger,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;result,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fold&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; res.&lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;(err.code &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;NOT_FOUND&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;404&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;500&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;({ error: err.message }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; res.&lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;200&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;(data),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;This is where the Reader pattern delivers the biggest practical win. Testing a function that uses &lt;code dir=&quot;auto&quot;&gt;ReaderTaskEither&lt;/code&gt; means providing a plain object with mock implementations. That is it.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { describe, it, expect, vi } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;vitest&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;describe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;findUser&quot;&lt;/span&gt;&lt;span&gt;, () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;it&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;returns the user when found&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mockDb&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;findUser: vi.&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;mockResolvedValue&lt;/span&gt;&lt;span&gt;({ id: &lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;, name: &lt;/span&gt;&lt;span&gt;&quot;Alice&quot;&lt;/span&gt;&lt;span&gt;, email: &lt;/span&gt;&lt;span&gt;&quot;alice@test.com&quot;&lt;/span&gt;&lt;span&gt; }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;findUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;({ db: mockDb }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isRight&lt;/span&gt;&lt;span&gt;(result)).&lt;/span&gt;&lt;span&gt;toBe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;expect&lt;/span&gt;&lt;span&gt;(mockDb.findUser).&lt;/span&gt;&lt;span&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;it&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;returns NOT_FOUND when user is null&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mockDb&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { findUser: vi.&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;mockResolvedValue&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;findUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;999&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;({ db: mockDb }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;expect&lt;/span&gt;&lt;span&gt;(result).&lt;/span&gt;&lt;span&gt;toEqual&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;({ code: &lt;/span&gt;&lt;span&gt;&quot;NOT_FOUND&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;&quot;User not found&quot;&lt;/span&gt;&lt;span&gt; }));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;describe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;getUserWithOrders&quot;&lt;/span&gt;&lt;span&gt;, () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;it&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;composes user and order lookups&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;getUserWithOrders&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;RTE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;db: { findUser: vi.&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;mockResolvedValue&lt;/span&gt;&lt;span&gt;({ id: &lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;, name: &lt;/span&gt;&lt;span&gt;&quot;Alice&quot;&lt;/span&gt;&lt;span&gt; }) },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderRepo: { findByUserId: vi.&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;mockResolvedValue&lt;/span&gt;&lt;span&gt;([{ id: &lt;/span&gt;&lt;span&gt;&quot;o1&quot;&lt;/span&gt;&lt;span&gt;, total: &lt;/span&gt;&lt;span&gt;50&lt;/span&gt;&lt;span&gt; }]) },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;logger: { info: vi.&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;() },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isRight&lt;/span&gt;&lt;span&gt;(result)).&lt;/span&gt;&lt;span&gt;toBe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Compare this with the NestJS testing equivalent:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// NestJS testing setup&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; Test.&lt;/span&gt;&lt;span&gt;createTestingModule&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;providers: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UserService,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ provide: UserRepository, useValue: mockUserRepo },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ provide: &lt;/span&gt;&lt;span&gt;&quot;Logger&quot;&lt;/span&gt;&lt;span&gt;, useValue: mockLogger },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ provide: &lt;/span&gt;&lt;span&gt;&quot;Database&quot;&lt;/span&gt;&lt;span&gt;, useValue: mockDb },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}).&lt;/span&gt;&lt;span&gt;compile&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;service&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt;&gt;(UserService);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; service.&lt;/span&gt;&lt;span&gt;getUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The NestJS version requires importing &lt;code dir=&quot;auto&quot;&gt;Test&lt;/code&gt; from &lt;code dir=&quot;auto&quot;&gt;@nestjs/testing&lt;/code&gt;, creating a module, registering providers, compiling the module, and resolving the service. The Reader version calls a function with an object.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;why-this-beats-ioc-containers&quot;&gt;Why This Beats IoC Containers&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No runtime overhead.&lt;/strong&gt; No container instantiation, no reflection, no metadata emission. &lt;code dir=&quot;auto&quot;&gt;ReaderTaskEither&lt;/code&gt; compiles down to plain function calls.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tree-shakeable.&lt;/strong&gt; Everything is functions and types. Bundlers eliminate unused code normally.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type-safe at compile time.&lt;/strong&gt; If you forget to provide a dependency, the compiler tells you. Not a runtime error — a red squiggle in your editor before you save the file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No decorators or metadata.&lt;/strong&gt; No &lt;code dir=&quot;auto&quot;&gt;emitDecoratorMetadata&lt;/code&gt; in your tsconfig. No &lt;code dir=&quot;auto&quot;&gt;reflect-metadata&lt;/code&gt; import. No experimental features.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Works everywhere.&lt;/strong&gt; Browser, Node, Deno, Bun, Cloudflare Workers. No environment-specific runtime requirements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependencies are explicit.&lt;/strong&gt; Every function’s signature declares exactly what it needs. Read the type, know the contract.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing is trivial.&lt;/strong&gt; Provide a plain object with mocks. No container setup, no module configuration, no &lt;code dir=&quot;auto&quot;&gt;@Injectable()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incremental adoption.&lt;/strong&gt; You can use &lt;code dir=&quot;auto&quot;&gt;ReaderTaskEither&lt;/code&gt; in one module without converting your entire codebase. It composes with existing code.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Install the library:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@oofp/core&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Start with these resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/reader-task-either/&quot;&gt;ReaderTaskEither reference&lt;/a&gt; — full API documentation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/guides/dependency-injection/&quot;&gt;Dependency injection guide&lt;/a&gt; — patterns for structuring applications&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/reader/&quot;&gt;Reader reference&lt;/a&gt; — the synchronous building block&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The pattern scales from a single function to an entire application architecture. Start by replacing one service class with a function that returns &lt;code dir=&quot;auto&quot;&gt;ReaderTaskEither&lt;/code&gt;. Chain it with another. Watch the compiler infer your dependency graph. You will not go back to decorators.&lt;/p&gt;</content:encoded><category>typescript</category><category>functional-programming</category><category>dependency-injection</category></item><item><title>Functional Error Handling in TypeScript: Beyond try-catch</title><link>https://oofp.pages.dev/blog/functional-error-handling-typescript/</link><guid isPermaLink="true">https://oofp.pages.dev/blog/functional-error-handling-typescript/</guid><description>Learn how to handle errors in TypeScript using Either and TaskEither monads instead of try-catch blocks. Type-safe, composable, and production-ready patterns.

</description><pubDate>Sun, 15 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every TypeScript developer has written something like this:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; db.&lt;/span&gt;&lt;span&gt;findUser&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;user) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;User not found&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; user;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The function signature says it returns a &lt;code dir=&quot;auto&quot;&gt;User&lt;/code&gt;. But that’s a lie. It might throw, and nothing in the type system warns you about it. The caller has to remember to wrap it in &lt;code dir=&quot;auto&quot;&gt;try-catch&lt;/code&gt;, hope they handle the right error type, and accept that the compiler won’t help if they forget.&lt;/p&gt;
&lt;p&gt;This is the fundamental problem with exception-based error handling in TypeScript: &lt;strong&gt;errors are invisible in function signatures&lt;/strong&gt;. They travel through a hidden channel that the type system cannot track.&lt;/p&gt;
&lt;p&gt;There is a better way.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-problem-with-try-catch&quot;&gt;The Problem with try-catch&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Consider a typical API call:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUserOrders&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt;(userId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;orders&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt;(user.id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;enriched&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; orders.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;order,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userName: user.name,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; enriched;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (error) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// What type is `error`? We don&apos;t know.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Did fetchUser throw? Or fetchOrders?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Is it a network error? A validation error? A parsing error?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;console.&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Something went wrong:&quot;&lt;/span&gt;&lt;span&gt;, error);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; [];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Three problems stand out:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Lost type information.&lt;/strong&gt; The &lt;code dir=&quot;auto&quot;&gt;catch&lt;/code&gt; block receives &lt;code dir=&quot;auto&quot;&gt;unknown&lt;/code&gt;. You have to guess or use &lt;code dir=&quot;auto&quot;&gt;instanceof&lt;/code&gt; chains to figure out what went wrong.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invisible failure modes.&lt;/strong&gt; Nothing in the function signature indicates it can fail. Callers see &lt;code dir=&quot;auto&quot;&gt;Promise&amp;#x3C;Order[]&gt;&lt;/code&gt; and might not realize they need error handling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Broken composition.&lt;/strong&gt; You cannot chain operations cleanly. Every step might throw, so you either nest &lt;code dir=&quot;auto&quot;&gt;try-catch&lt;/code&gt; blocks or lump everything into one, losing granularity.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;h2 id=&quot;either-type-safe-errors-for-sync-operations&quot;&gt;Either: Type-Safe Errors for Sync Operations&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Either&amp;#x3C;E, A&gt;&lt;/code&gt; is a type that explicitly represents a computation that can succeed with a value of type &lt;code dir=&quot;auto&quot;&gt;A&lt;/code&gt; or fail with an error of type &lt;code dir=&quot;auto&quot;&gt;E&lt;/code&gt;. The error type is right there in the signature — the compiler enforces it.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ValidationError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;field&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validateAge&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ValidationError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Number&lt;/span&gt;&lt;span&gt;(input);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;isNaN&lt;/span&gt;&lt;span&gt;(n)) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;({ field: &lt;/span&gt;&lt;span&gt;&quot;age&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;&quot;Not a number&quot;&lt;/span&gt;&lt;span&gt; });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (n &lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;150&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;({ field: &lt;/span&gt;&lt;span&gt;&quot;age&quot;&lt;/span&gt;&lt;span&gt;, message: &lt;/span&gt;&lt;span&gt;&quot;Out of range&quot;&lt;/span&gt;&lt;span&gt; });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(n);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The return type &lt;code dir=&quot;auto&quot;&gt;Either&amp;#x3C;ValidationError, number&gt;&lt;/code&gt; tells you everything: this function might fail with a &lt;code dir=&quot;auto&quot;&gt;ValidationError&lt;/code&gt;, or succeed with a &lt;code dir=&quot;auto&quot;&gt;number&lt;/code&gt;. No surprises. No hidden exceptions.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;composing-with-pipe&quot;&gt;Composing with pipe&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The real power of &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt; emerges when you compose operations using &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ParseError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parseNumber&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ParseError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Number&lt;/span&gt;&lt;span&gt;(s);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;isNaN&lt;/span&gt;&lt;span&gt;(n) &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`&quot;${&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;}&quot; is not a number`&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(n);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ensurePositive&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ParseError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(n) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Must be positive&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ensureBelow&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;max&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ParseError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt; max &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(n) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Must be below ${&lt;/span&gt;&lt;span&gt;max&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;parseNumber&lt;/span&gt;&lt;span&gt;(input),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;(ensurePositive),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ensureBelow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;42&quot;&lt;/span&gt;&lt;span&gt;);    &lt;/span&gt;&lt;span&gt;// Right(42)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;-5&quot;&lt;/span&gt;&lt;span&gt;);    &lt;/span&gt;&lt;span&gt;// Left(&quot;Must be positive&quot;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;abc&quot;&lt;/span&gt;&lt;span&gt;);   &lt;/span&gt;&lt;span&gt;// Left(&quot;\&quot;abc\&quot; is not a number&quot;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;150&quot;&lt;/span&gt;&lt;span&gt;);   &lt;/span&gt;&lt;span&gt;// Left(&quot;Must be below 100&quot;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Each step in the pipeline short-circuits on error. If &lt;code dir=&quot;auto&quot;&gt;parseNumber&lt;/code&gt; fails, &lt;code dir=&quot;auto&quot;&gt;ensurePositive&lt;/code&gt; never runs. The error propagates automatically, and its type is tracked at every step.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;validating-structured-data&quot;&gt;Validating structured data&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code dir=&quot;auto&quot;&gt;sequenceObject&lt;/code&gt; to validate multiple fields at once:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserForm&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;age&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validateForm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Record&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;UserForm&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sequenceObject&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;name: &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;data.name,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Name is required&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; s.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(s) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Name too short&quot;&lt;/span&gt;&lt;span&gt;)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;email: &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;data.email,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Email is required&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; s.&lt;/span&gt;&lt;span&gt;includes&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;@&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;(s) &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Invalid email&quot;&lt;/span&gt;&lt;span&gt;)),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;age: &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;data.age,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromNullable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Age is required&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;(parseNumber),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;(ensurePositive),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The result is either a fully validated &lt;code dir=&quot;auto&quot;&gt;UserForm&lt;/code&gt; or the first validation error. The compiler knows exactly what you’ll get.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;taskeither-async-error-handling&quot;&gt;TaskEither: Async Error Handling&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Most real applications involve async operations — API calls, database queries, file I/O. &lt;code dir=&quot;auto&quot;&gt;TaskEither&amp;#x3C;E, A&gt;&lt;/code&gt; extends &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt; into the async world:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Either&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;&gt;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;It’s a lazy function that, when executed, returns a &lt;code dir=&quot;auto&quot;&gt;Promise&lt;/code&gt; that &lt;strong&gt;always resolves&lt;/strong&gt; to an &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt;. No rejections, no unhandled promises — just typed success or failure.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; TE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task-either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpError&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;HttpError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`/api/users/${&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;res.ok) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; { status: res.status, message: res.statusText };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; res.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpError&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;tryCatch&lt;/code&gt; wraps the fallible async operation. If the promise rejects, the error is caught and mapped to your typed error via the callback. The resulting &lt;code dir=&quot;auto&quot;&gt;TaskEither&lt;/code&gt; never rejects.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;building-async-pipelines&quot;&gt;Building async pipelines&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Chain async operations the same way you chain sync ones:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TaskEither&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;HttpError&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;[]&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`/api/orders?userId=${&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;res.ok) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; { status: res.status, message: res.statusText };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; res.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;[]&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryCatch&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpError&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserWithOrders&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt;(userId),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt;(user.id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;orders&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ user, orders })),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code dir=&quot;auto&quot;&gt;fetchUser&lt;/code&gt; fails, &lt;code dir=&quot;auto&quot;&gt;fetchOrders&lt;/code&gt; never executes. The error type flows through the entire pipeline.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;error-recovery&quot;&gt;Error recovery&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code dir=&quot;auto&quot;&gt;orElse&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;chainLeft&lt;/code&gt; to recover from errors:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUserWithFallback&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;orElse&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;err.status &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;404&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;({ id, name: &lt;/span&gt;&lt;span&gt;&quot;Guest&quot;&lt;/span&gt;&lt;span&gt;, email: &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(err),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;collecting-independent-data&quot;&gt;Collecting independent data&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code dir=&quot;auto&quot;&gt;sequenceObject&lt;/code&gt; to combine multiple operations into a single result:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserDashboard&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sequenceObject&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user: &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orders: &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;settings: &lt;/span&gt;&lt;span&gt;fetchSettings&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// TaskEither&amp;#x3C;HttpError, { user: User; orders: Order[]; settings: Settings }&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Each operation runs sequentially. If any fails, execution stops and you get the first error. Need parallelism? Use &lt;code dir=&quot;auto&quot;&gt;concurrencyObject&lt;/code&gt; instead:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserDashboard&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;concurrencyObject&lt;/span&gt;&lt;span&gt;()({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user: &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orders: &lt;/span&gt;&lt;span&gt;fetchOrders&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;settings: &lt;/span&gt;&lt;span&gt;fetchSettings&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;resilience-with-retry&quot;&gt;Resilience with retry&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchUserReliable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;fetchUser&lt;/span&gt;&lt;span&gt;(id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;retry&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;maxRetries: &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;delay: &lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;skipIf&lt;/span&gt;&lt;span&gt;: (&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; err.status &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;404&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// don&apos;t retry &quot;not found&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;onError&lt;/span&gt;&lt;span&gt;: (&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; console.&lt;/span&gt;&lt;span&gt;warn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Retry: ${&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;bridging-to-the-outside-world&quot;&gt;Bridging to the Outside World&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;At the boundaries of your application — HTTP handlers, React components, CLI entry points — you need to extract the &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt; and produce a concrete result:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; TE &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/task-either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { pipe } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/pipe&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Express handler&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;app.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/users/:id&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;req&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;getUserWithOrders&lt;/span&gt;&lt;span&gt;(req.params.id),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fold&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ status: err.status, body: { error: err.message } }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({ status: &lt;/span&gt;&lt;span&gt;200&lt;/span&gt;&lt;span&gt;, body: data }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;task&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;task&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;res.&lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;(result.status).&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;(result.body);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;fold&lt;/code&gt; collapses both branches into a single type. No &lt;code dir=&quot;auto&quot;&gt;try-catch&lt;/code&gt; anywhere. The error type is explicit, the happy path is clean, and the compiler ensures you handle both cases.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;why-this-matters&quot;&gt;Why This Matters&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Switching from &lt;code dir=&quot;auto&quot;&gt;try-catch&lt;/code&gt; to &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;TaskEither&lt;/code&gt; gives you three concrete advantages:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Type safety.&lt;/strong&gt; Every function signature declares its failure modes. If a function returns &lt;code dir=&quot;auto&quot;&gt;TaskEither&amp;#x3C;HttpError | ValidationError, User&gt;&lt;/code&gt;, you know exactly what can go wrong. The compiler enforces exhaustive handling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Composability.&lt;/strong&gt; Operations compose with &lt;code dir=&quot;auto&quot;&gt;pipe&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;chain&lt;/code&gt;, and &lt;code dir=&quot;auto&quot;&gt;map&lt;/code&gt;. You build complex pipelines from small, testable functions. Error propagation is automatic — no manual &lt;code dir=&quot;auto&quot;&gt;try-catch&lt;/code&gt; threading.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Testability.&lt;/strong&gt; Functions that return &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt; are pure. They don’t throw, they don’t have hidden side effects, and they’re trivial to test:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { expect, test } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;vitest&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; E &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@oofp/core/either&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;parsePercentage rejects negative numbers&quot;&lt;/span&gt;&lt;span&gt;, () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parsePercentage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;-5&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isLeft&lt;/span&gt;&lt;span&gt;(result)).&lt;/span&gt;&lt;span&gt;toBe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;expect&lt;/span&gt;&lt;span&gt;(result).&lt;/span&gt;&lt;span&gt;toEqual&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;E&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Must be positive&quot;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;No mocking &lt;code dir=&quot;auto&quot;&gt;try-catch&lt;/code&gt;, no asserting that something throws — just straightforward input-output testing.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Install &lt;code dir=&quot;auto&quot;&gt;@oofp/core&lt;/code&gt; and start with the building blocks:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@oofp/core&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/either/&quot;&gt;Either documentation&lt;/a&gt; — synchronous error handling&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/task-either/&quot;&gt;TaskEither documentation&lt;/a&gt; — async error handling&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oofp.pages.dev/core/composition/&quot;&gt;Pipe, Flow &amp;#x26; Compose&lt;/a&gt; — function composition&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The patterns scale from small validations to full application architectures. Start by replacing one &lt;code dir=&quot;auto&quot;&gt;try-catch&lt;/code&gt; block with &lt;code dir=&quot;auto&quot;&gt;Either&lt;/code&gt;, and the benefits will compound as you build on top of it.&lt;/p&gt;</content:encoded><category>typescript</category><category>functional-programming</category><category>error-handling</category></item></channel></rss>