ploeh blog 2022-05-16T07:46:11+00:00 Mark Seemann danish software design https://blog.ploeh.dk The Identity monad https://blog.ploeh.dk/2022/05/16/the-identity-monad 2022-05-16T05:49:00+00:00 Mark Seemann <div id="post"> <p> <em>Probably one of the least useful monads. An article for object-oriented developers.</em> </p> <p> This article is an instalment in <a href="/2022/03/28/monads">an article series about monads</a>. </p> <p> <a href="/2018/09/03/the-identity-functor">The Identity functor</a> is another example of a functor that also forms a monad. Contrary to useful monads like <a href="/2022/04/19/the-list-monad">list</a>, <a href="/2022/04/25/the-maybe-monad">Maybe</a>, and <a href="/2022/05/09/an-either-monad">Either</a>, the Identity monad isn't particularly useful. In <a href="https://www.haskell.org">Haskell</a> it serves a few niche positions, for example when it comes to monad transformers. It's possible to define abstractions at a higher level in Haskell than it is in many other languages. Some of those abstractions involve monads. The Identity monad can plug into these abstractions as a 'do-nothing' monad, a bit like the <a href="https://en.wikipedia.org/wiki/Null_object_pattern">Null Object pattern</a> can supply a 'do-nothing' implementation of an interface. </p> <p> Other languages with which I'm proficient (C#, <a href="https://fsharp.org">F#</a>) don't enable that kind of abstraction, and I've never felt the need to actually <em>use</em> the Identity monad in those languages. Still, the Identity monad exists mathematically and conceptually, and it can be useful to know of that existence. This implies, like the Null Object pattern, that some abstractions can be simplified by 'plugging in' the Identity monad. The alternative would have had to involve some hand-waving about special cases. </p> <p> The code in this article continues the implementation shown in the article about <a href="/2018/09/03/the-identity-functor">the Identity functor</a>. </p> <h3 id="db0c7e97a3ee4477a96078c22cf89330"> SelectMany <a href="#db0c7e97a3ee4477a96078c22cf89330" title="permalink">#</a> </h3> <p> A monad must define either a <em>bind</em> or <em>join</em> function. In C#, monadic bind is called <code>SelectMany</code>. For <code>Identity&lt;T&gt;</code> the implementation is trivial: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Identity&lt;TResult&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">TResult</span>&gt;(Func&lt;T,&nbsp;Identity&lt;TResult&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;selector(Item); }</pre> </p> <p> This is an instance method on <code>Identity&lt;T&gt;</code>, which means that the <code>Item</code> property has the type <code>T</code>. Since the <code>selector</code> return a new <code>Identity&lt;TResult&gt;</code>, the method can simply return that value. </p> <h3 id="9e4f558b6a7542148090044ab8e19060"> Query syntax <a href="#9e4f558b6a7542148090044ab8e19060" title="permalink">#</a> </h3> <p> As usual, you can implement C# query syntax with a boilerplate overload of <code>SelectMany</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Identity&lt;TResult&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">U</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Identity&lt;U&gt;&gt;&nbsp;<span style="color:#1f377f;">k</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;U,&nbsp;TResult&gt;&nbsp;<span style="color:#1f377f;">s</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;k(x).Select(<span style="color:#1f377f;">y</span>&nbsp;=&gt;&nbsp;s(x,&nbsp;y))); }</pre> </p> <p> The implementation is the same as in the previous articles in this article series. If it looks a little different than, say, the implementation for <a href="/2022/04/25/the-maybe-monad">the Maybe monad</a>, it's only because this <code>SelectMany</code> overload is an instance method, whereas the Maybe implementation is an extension method. </p> <p> Query syntax enables syntactic sugar like this: </p> <p> <pre>Identity&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&nbsp;<span style="color:blue;">from</span>&nbsp;x&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Identity&lt;<span style="color:blue;">int</span>&gt;(39) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;y&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Identity&lt;<span style="color:blue;">string</span>&gt;(<span style="color:#a31515;">&quot;foo&quot;</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;x&nbsp;+&nbsp;y.Length;</pre> </p> <p> The C# compiler infers that <code>x</code> is an <code>int</code> and <code>y</code> is a <code>string</code>. </p> <h3 id="9ee27fde0adc488b82f4c5ec358bc17c"> Flatten <a href="#9ee27fde0adc488b82f4c5ec358bc17c" title="permalink">#</a> </h3> <p> As <a href="/2022/03/28/monads">the monad introduction</a> also points out, if you have monadic bind (<code>SelectMany</code>) you can always implement a function to flatten a nested <a href="/2018/03/22/functors">functor</a>. This function is sometimes called <em>join</em> and sometimes (perhaps more intuitively) <em>flatten</em>. Here I've chosen to call it <code>Flatten</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Identity&lt;T&gt;&nbsp;<span style="color:#74531f;">Flatten</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;Identity&lt;Identity&lt;T&gt;&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x); }</pre> </p> <p> Even though the other methods shown so far have been instance methods, <code>Flatten</code> has to be an extension method, since the source is a nested <code>Identity&lt;Identity&lt;T&gt;&gt;</code>. There's no class of that specific type - only <code>Identity&lt;T&gt;</code>. </p> <p> If there's one useful aspect of the Identity monad, it may be that it reveals the concept of a nested functor in all its triviality: </p> <p> <pre>Identity&lt;Identity&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">nested</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Identity&lt;Identity&lt;<span style="color:blue;">string</span>&gt;&gt;(<span style="color:blue;">new</span>&nbsp;Identity&lt;<span style="color:blue;">string</span>&gt;(<span style="color:#a31515;">&quot;bar&quot;</span>)); Identity&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">flattened</span>&nbsp;=&nbsp;nested.Flatten();</pre> </p> <p> Recall: A monad is a functor you can flatten. </p> <h3 id="be7d9a35a21a48498f469ae3a3357bc0"> Return <a href="#be7d9a35a21a48498f469ae3a3357bc0" title="permalink">#</a> </h3> <p> Apart from monadic bind, a monad must also define a way to put a normal value into the monad. Conceptually, I call this function <em>return</em> (because that's the name that Haskell uses). You don't, however, have to define a static method called <code>Return</code>. What's of importance is that the capability exists. For <code>Identity&lt;T&gt;</code> in C# the idiomatic way would be to use a constructor. This constructor does double duty as monadic <em>return</em>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Identity</span>(T&nbsp;<span style="color:#1f377f;">item</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Item&nbsp;=&nbsp;item; }</pre> </p> <p> In other words, <em>return</em> just wraps a value in the <code>Identity&lt;T&gt;</code> <a href="https://bartoszmilewski.com/2014/01/14/functors-are-containers">container</a>. </p> <h3 id="6bc314d479564086a2acd46dbccf44dd"> Left identity <a href="#6bc314d479564086a2acd46dbccf44dd" title="permalink">#</a> </h3> <p> We need to identify the <em>return</em> function in order to examine <a href="/2022/04/11/monad-laws">the monad laws</a>. Let's see what they look like for the Identity monad, starting with the left identity law. </p> <p> <pre>[Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityHasLeftIdentity</span>(Func&lt;<span style="color:blue;">int</span>,&nbsp;Identity&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Identity&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Identity&lt;<span style="color:blue;">int</span>&gt;(i); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(@return(a).SelectMany(h),&nbsp;h(a)); }</pre> </p> <p> This example is a bit different compared to the previous examples, since it uses <a href="https://fscheck.github.io/FsCheck/">FsCheck</a> 2.11.0 and <a href="https://xunit.net/">xUnit.net</a> 2.4.0. FScheck can generate arbitrary functions in addition to arbitrary values, so I've simply asked it to generate some arbitrary <code>h</code> functions. </p> <h3 id="b97ac93ff7d74d0ba165dc847f604d0d"> Right identity <a href="#b97ac93ff7d74d0ba165dc847f604d0d" title="permalink">#</a> </h3> <p> In a similar manner, we can showcase the right identity law as a test. </p> <p> <pre>[Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityHasRightIdentity</span>(Func&lt;<span style="color:blue;">string</span>,&nbsp;Identity&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Identity&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Identity&lt;<span style="color:blue;">int</span>&gt;(i); &nbsp;&nbsp;&nbsp;&nbsp;Identity&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(@return),&nbsp;m); }</pre> </p> <p> As always, even a property-based test constitutes no <em>proof</em> that the law holds. I show it only to illustrate what the laws look like in 'real' code. </p> <h3 id="fc12cf871df6428fb9e14906e9c65707"> Associativity <a href="#fc12cf871df6428fb9e14906e9c65707" title="permalink">#</a> </h3> <p> The last monad law is the associativity law that describes how (at least) three functions compose. </p> <p> <pre>[Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityIsAssociative</span>( &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Identity&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Identity&lt;<span style="color:blue;">byte</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">byte</span>,&nbsp;Identity&lt;TimeSpan&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Identity&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(g).SelectMany(h),&nbsp;m.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h))); }</pre> </p> <p> This property once more relies on FsCheck's ability to generate arbitrary <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. </p> <h3 id="33f53ea7db964a62a542244b9de58499"> F# <a href="#33f53ea7db964a62a542244b9de58499" title="permalink">#</a> </h3> <p> While the <code>Identity</code> monad is built into the Haskell standard library, there's no Identity monad in F#. While it can be occasionally useful in Haskell, Identity is as useless in F# as it is in C#. Again, that doesn't imply that you can't define it. You can: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;Identity&lt;&#39;a&gt;&nbsp;=&nbsp;Identity&nbsp;<span style="color:blue;">of</span>&nbsp;&#39;a <span style="color:blue;">module</span>&nbsp;Identity&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Identity&lt;&#39;a&gt;&nbsp;-&gt;&nbsp;&#39;a</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;get&nbsp;(Identity&nbsp;x)&nbsp;=&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;&#39;b)&nbsp;-&gt;&nbsp;Identity&lt;&#39;a&gt;&nbsp;-&gt;&nbsp;Identity&lt;&#39;b&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;map&nbsp;f&nbsp;(Identity&nbsp;x)&nbsp;=&nbsp;Identity&nbsp;(f&nbsp;x) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;Identity&lt;&#39;b&gt;)&nbsp;-&gt;&nbsp;Identity&lt;&#39;a&gt;&nbsp;-&gt;&nbsp;Identity&lt;&#39;b&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;bind&nbsp;f&nbsp;(Identity&nbsp;x)&nbsp;:&nbsp;Identity&lt;_&gt;&nbsp;=&nbsp;f&nbsp;x</pre> </p> <p> Here I've repeated the functor implementation from <a href="/2018/09/03/the-identity-functor">the article about the Identity functor</a>, but now also included the <code>bind</code> function. </p> <p> You can use such a module to support syntactic sugar in the form of <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/computation-expressions">computation expressions</a>: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;IdentityBuilder()&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">member</span>&nbsp;_.Bind(x,&nbsp;f)&nbsp;=&nbsp;Identity.bind&nbsp;f&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">member</span>&nbsp;_.Return&nbsp;x&nbsp;=&nbsp;Identity&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">member</span>&nbsp;_.ReturnFrom&nbsp;x&nbsp;=&nbsp;x <span style="color:blue;">let</span>&nbsp;identity&nbsp;=&nbsp;IdentityBuilder&nbsp;()</pre> </p> <p> This enables you to write code like this: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;i&nbsp;=&nbsp;identity&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;x&nbsp;=&nbsp;Identity&nbsp;<span style="color:#a31515;">&quot;corge&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;y&nbsp;=&nbsp;Identity&nbsp;47 &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;y&nbsp;-&nbsp;x.Length&nbsp;}</pre> </p> <p> Here, <code>i</code> is a value of the type <code>Identity&lt;int&gt;</code>. </p> <h3 id="7b30db7a0912447c8b3aa6d9da8691e9"> Conclusion <a href="#7b30db7a0912447c8b3aa6d9da8691e9" title="permalink">#</a> </h3> <p> If the Identity monad is useful in languages like C# and F#, I have yet to encounter a use case. Even so, it exists. It is also, perhaps, the most naked illustration of what a functor and monad is. As such, I think it may be helpful to study. </p> <p> <strong>Next:</strong> The Lazy monad. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. An Either monad https://blog.ploeh.dk/2022/05/09/an-either-monad 2022-05-09T06:30:00+00:00 Mark Seemann <div id="post"> <p> <em>The Either sum type forms a monad. An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2022/03/28/monads">an article series about monads</a>. </p> <p> The Either <a href="https://en.wikipedia.org/wiki/Tagged_union">sum type</a> is a useful data type that <a href="/2019/01/14/an-either-functor">forms a functor</a>. Actually, <a href="/2019/01/07/either-bifunctor">it forms two functors</a>. Like many other useful functors, it also forms a monad. Again, more than one monad is possible. In this article I'll focus on the 'usual' monad instance where mapping takes place over the right side. If you swap left and right, however, you can also define a monad that maps over the left side. Try it; it's a good exercise. </p> <p> <em>Either</em> is also known as <em>Result</em>, in which case <em>right</em> is usually called <em>success</em> or <em>OK</em>, while <em>left</em> is called <em>error</em> or <em>failure</em>. </p> <p> In this article, I'll base the C# implementation on the code from <a href="/2018/06/11/church-encoded-either">Church-encoded Either</a>. </p> <h3 id="d098a362e231405fb5a3b65cbc59e5f4"> Join <a href="#d098a362e231405fb5a3b65cbc59e5f4" title="permalink">#</a> </h3> <p> A monad must define either a <em>bind</em> or <em>join</em> function. As outlined in <a href="/2022/03/28/monads">the introduction to monads</a>, if you have one, you can use it to implement the other. For variety's sake, in this article series I do both. I also vary the names when there's no clear <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a> naming convention. For this version of Either, I've chosen to start with a method called <code>Join</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEither&lt;L,&nbsp;R&gt;&nbsp;<span style="color:#74531f;">Join</span>&lt;<span style="color:#2b91af;">L</span>,&nbsp;<span style="color:#2b91af;">R</span>&gt;(<span style="color:blue;">this</span>&nbsp;IEither&lt;L,&nbsp;IEither&lt;L,&nbsp;R&gt;&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onLeft:&nbsp;&nbsp;<span style="color:#1f377f;">l</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Left&lt;L,&nbsp;R&gt;(l), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onRight:&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;r); }</pre> </p> <p> This method flattens a nested Either value. If the outer Either is a <em>left</em> case, the method returns a <code>new Left&lt;L, R&gt;(l)</code> value, which fits the required return type. If the outer Either is a <em>right</em> case, it contains another, nested Either value that it can return. </p> <p> As already described in the article <a href="/2018/06/11/church-encoded-either">Church-encoded Either</a>, you can use Either values instead of exceptions. While that article already gives an example, the Either in that value isn't nested. This, however, can easily happen when you try to compose calculations that may fail. Another example may involve parsing. Here are two simple parsers: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#74531f;">TryParseDate</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">candidate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(DateTime.TryParse(candidate,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">d</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Right&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;(d); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Left&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;(candidate); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#74531f;">TryParseDuration</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">candidate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(TimeSpan.TryParse(candidate,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">ts</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Right&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;(ts); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Left&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;(candidate); }</pre> </p> <p> These functions try to <a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/">parse candidate values to more structured data types</a>. If parsing fails, they return the <a href="/2020/11/30/name-by-role">candidate value</a> so that calling code may get a chance to inspect and report the string that caused a failure. What happens if you try to compose these two functions? </p> <p> <pre>IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#1f377f;">dt</span>&nbsp;=&nbsp;TryParseDate(<span style="color:#a31515;">&quot;2022-03-21&quot;</span>); IEither&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&nbsp;TryParseDuration(<span style="color:#a31515;">&quot;2&quot;</span>); IEither&lt;<span style="color:blue;">string</span>,&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&gt;&nbsp;<span style="color:#1f377f;">nested</span>&nbsp;=&nbsp;dt.Select(<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;ts.Select(<span style="color:#1f377f;">dur</span>&nbsp;=&gt;&nbsp;d&nbsp;+&nbsp;dur));</pre> </p> <p> Composing the results of these two functions produces a nested result that you can flatten with <code>Join</code>: </p> <p> <pre>IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#1f377f;">flattened</span>&nbsp;=&nbsp;nested.Join();</pre> </p> <p> Using <code>Join</code> for that purpose is, however, often awkward, so a better option is to flatten as you go. </p> <h3 id="2ae2ab4c8dea429cae52de32dd5c3a2d"> SelectMany <a href="#2ae2ab4c8dea429cae52de32dd5c3a2d" title="permalink">#</a> </h3> <p> Monadic bind (in C# called <code>SelectMany</code>) enables you to flatten as you go. As also shown in <a href="/2022/03/28/monads">the monad introduction</a>, if you already have <code>Join</code> you can always implement <code>SelectMany</code> like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEither&lt;L,&nbsp;R1&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">L</span>,&nbsp;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">R1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IEither&lt;L,&nbsp;R&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;R,&nbsp;IEither&lt;L,&nbsp;R1&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.Select(selector).Join(); }</pre> </p> <p> The <code>SelectMany</code> method makes the above composition a little easier: </p> <p> <pre>IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#1f377f;">result</span>&nbsp;=&nbsp;dt.SelectMany(<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;ts.Select(<span style="color:#1f377f;">dur</span>&nbsp;=&gt;&nbsp;d&nbsp;+&nbsp;dur));</pre> </p> <p> Instead of having to flatten a nested result, you can flatten as you go. I think that <a href="https://www.scala-lang.org/">Scala</a>'s <code>flatMap</code> is a better name for that operation than <code>SelectMany</code>, but the behaviour is the same. If you're wondering why it's called <code>SelectMany</code>, see my attempt at an explanation in the article about the <a href="/2022/04/19/the-list-monad">list monad</a>. The name makes modest sense in that context, but in the context of Either, that meaning is lost. </p> <h3 id="cfe7b3b6f8104ec5b766407eacaaa458"> Query syntax <a href="#cfe7b3b6f8104ec5b766407eacaaa458" title="permalink">#</a> </h3> <p> Perhaps you still find the above composition awkward. After all, you have to nest a <code>Select</code> inside a <code>SelectMany</code>. Is there a simpler way? </p> <p> One option is to use query syntax, but in order to do that, you must (again as outlined in the <a href="/2022/03/28/monads">monad introduction</a>) add a special boilerplate <code>SelectMany</code> overload: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEither&lt;L,&nbsp;R1&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">L</span>,&nbsp;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">R1</span>,&nbsp;<span style="color:#2b91af;">U</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IEither&lt;L,&nbsp;R&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;R,&nbsp;IEither&lt;L,&nbsp;U&gt;&gt;&nbsp;<span style="color:#1f377f;">k</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;R,&nbsp;U,&nbsp;R1&gt;&nbsp;<span style="color:#1f377f;">s</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;k(x).Select(<span style="color:#1f377f;">y</span>&nbsp;=&gt;&nbsp;s(x,&nbsp;y))); }</pre> </p> <p> This enables you to rewrite the above composition like this: </p> <p> <pre>IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#1f377f;">result</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;d&nbsp;<span style="color:blue;">in</span>&nbsp;dt &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;dur&nbsp;<span style="color:blue;">in</span>&nbsp;ts &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;d&nbsp;+&nbsp;dur;</pre> </p> <p> It's often a question of <a href="/2020/10/12/subjectivity">subjectivity</a> whether you like one alternative over the other, but the behaviour is the same. </p> <h3 id="064ab5098d3944b1be8bc24247592fb0"> Return <a href="#064ab5098d3944b1be8bc24247592fb0" title="permalink">#</a> </h3> <p> Apart from monadic bind, a monad must also define a way to put a normal value into the monad. Conceptually, I call this function <em>return</em> (because that's the name that Haskell uses). You don't, however, have to define a static method called <code>Return</code>. What's of importance is that the capability exists. For <code>Either&lt;L, R&gt;</code> in C# the idiomatic way would be to use a constructor. This constructor does double duty as monadic <em>return</em>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Right</span>(R&nbsp;<span style="color:#1f377f;">right</span>)</pre> </p> <p> In other words, <em>return</em> wraps a value in a <em>right</em> case. </p> <p> Why not the <em>left</em> case? Because it wouldn't type-check. A <em>return</em> function should take a value of the type <code>R</code> and return an <code>IEither&lt;L, R&gt;</code>. The <code>Left</code> constructor, however, doesn't take an <code>R</code> value - it takes an <code>L</code> value. </p> <h3 id="f0fb650204c043229df4967c22c4d6ec"> Left identity <a href="#f0fb650204c043229df4967c22c4d6ec" title="permalink">#</a> </h3> <p> We need to identify the <em>return</em> function in order to examine <a href="/2022/04/11/monad-laws">the monad laws</a>. Let's see what they look like for the Either monad, starting with the left identity law. </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;2&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;2.3:00&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;4.5:30&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;0:33:44&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">LeftIdentityLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Right&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">string</span>&gt;(s); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;TryParseDuration; &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(@return(a).SelectMany(h),&nbsp;h(a)); }</pre> </p> <p> As always, even a parametrised test constitutes no <em>proof</em> that the law holds. I show the tests to illustrate what the laws look like in 'real' code. </p> <h3 id="d158a758e9dc40149c7676a83398d17d"> Right identity <a href="#d158a758e9dc40149c7676a83398d17d" title="permalink">#</a> </h3> <p> In a similar manner, we can showcase the right identity law as a test. </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;2022-03-22&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;2022-03-21T16:57&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">RightIdentityLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;TryParseDate; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;DateTime,&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Right&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;(d); &nbsp;&nbsp;&nbsp;&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(@return),&nbsp;m); }</pre> </p> <p> The parameters supplied as <code>a</code> will cause <code>m</code> to be both <code>Left</code> and <code>Right</code> values, but the test demonstrates that the law holds in both cases. </p> <h3 id="ff7794ca964b4dfdb588251f264c7c11"> Associativity <a href="#ff7794ca964b4dfdb588251f264c7c11" title="permalink">#</a> </h3> <p> The last monad law is the associativity law that describes how (at least) three functions compose. We're going to need three functions. I'm going to reuse <code>TryParseDuration</code> and add two new Either-valued functions: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#74531f;">DaysForward</span>(TimeSpan&nbsp;<span style="color:#1f377f;">ts</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(ts&nbsp;&lt;&nbsp;TimeSpan.Zero) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Left&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">double</span>&gt;(<span style="color:#a31515;">$&quot;Negative&nbsp;durations&nbsp;not&nbsp;allowed:&nbsp;</span>{ts}<span style="color:#a31515;">.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Right&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">double</span>&gt;(ts.TotalDays); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#74531f;">Nat</span>(<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">d</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(d&nbsp;%&nbsp;1&nbsp;!=&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Left&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;(<span style="color:#a31515;">$&quot;Non-integers&nbsp;not&nbsp;allowed:&nbsp;</span>{d}<span style="color:#a31515;">.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(d&nbsp;&lt;&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Left&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;(<span style="color:#a31515;">$&quot;Non-positive&nbsp;numbers&nbsp;not&nbsp;allowed:&nbsp;</span>{d}<span style="color:#a31515;">.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Right&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;((<span style="color:blue;">int</span>)d); }</pre> </p> <p> These silly functions are only here for purposes of demonstration. Don't try to infer any deep meaning from them. </p> <p> Designating them <code>f</code>, <code>g</code>, and <code>h</code>, we can use them to express the monad associativity law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;2&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;-2.3:00&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;4.5:30&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;0:33:44&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;0&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">AssociativityLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;TryParseDuration; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TimeSpan,&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">double</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;DaysForward; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;Nat; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(g).SelectMany(h),&nbsp;m.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h))); }</pre> </p> <p> The test cases supplied via the <code>[InlineData]</code> attributes comprise a set of values that make their way through the composition to varying degrees. <code>"2"</code> makes it all the way through to a <code>Right</code> value, because it encodes a two-day duration. It's both a positive value, greater than zero, and an integer. The other test cases become <code>Left</code> values at various stages in the composition, being either a non-number, fractional, zero, or negative. </p> <h3 id="b409ce7af135433eb275832d2c45ffde"> Conclusion <a href="#b409ce7af135433eb275832d2c45ffde" title="permalink">#</a> </h3> <p> Either (AKA Result) is another useful data structure that forms a monad. You can use it instead of throwing exceptions. Its monadic nature enables you to compose multiple Either-valued functions in a sane and elegant way. </p> <p> <strong>Next:</strong> <a href="/2022/05/16/the-identity-monad">The Identity monad</a>. </p> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. At the boundaries, applications aren't functional https://blog.ploeh.dk/2022/05/02/at-the-boundaries-applications-arent-functional 2022-05-02T05:29:00+00:00 Mark Seemann <div id="post"> <p> <em>Ten years later.</em> </p> <p> In 2011 I published an article titled <a href="/2011/05/31/AttheBoundaries,ApplicationsareNotObject-Oriented">At the Boundaries, Applications are Not Object-Oriented</a>. It made the observation that at the edges of systems, where software interacts with either humans or other software, interactions aren't object-oriented. The data exchanged is exactly that: data. </p> <p> A common catchphrase about object-oriented design is that <em>objects are data with behaviour</em>. In a user interface, a REST API, at the command line, etcetera, data is transmitted, but behaviour is not. </p> <p> The article was one of those unfortunately unsatisfying articles that point out a problem without offering a solution. While I don't like to leave readers hanging like that, I on the other hand think that it's important sometimes to ask open-ended questions. <em>Here's a problem. Can anyone offer a solution?</em> </p> <p> People occasionally come by that old article and ask me if I've changed my mind since then. The short answer is that I believe that the problem persists. I may, however, today have another approach to it. </p> <h3 id="a438ebbc5a964854906bf0ac0991e0ba"> Functional programming <a href="#a438ebbc5a964854906bf0ac0991e0ba" title="permalink">#</a> </h3> <p> Starting around the time of the original article, I became interested in functional programming (FP). The more I've learned about it, the better it seems to address my concerns of eleven years ago. </p> <p> I don't know if FP is a silver bullet (although <a href="/2019/07/01/yes-silver-bullet">I'd like to think so</a>), but at least I find that I have fewer impedance mismatch issues than I did with object-oriented programming (OOP). In FP, after all, data is just data. </p> <p> Except when it isn't, but more about that later. </p> <p> It's easier to reconcile the FP notion of data with what actually goes on at the boundaries of a system. </p> <p> Perhaps I should clarify what I mean by the word <em>boundary</em>. This is where a software system interacts with the rest of the world. This is where it receives HTTP requests and answers with HTTP responses. This is where it queries its database. This is where it sends emails. This is where it reads files from disk. This is where it repaints user interfaces. In short, the outermost circle in <a href="/2013/12/03/layers-onions-ports-adapters-its-all-the-same">ports and adapters architecture</a>. </p> <p> Notice that what crosses the boundary tends to be data. JSON or XML documents, tabular data streams, flat files, etcetera. In OOP, your training tells you that you should associate some <em>behaviour</em> with data, and that's what creates dissonance. We introduce <a href="https://en.wikipedia.org/wiki/Data_transfer_object">Data Transfer Objects</a> (DTO) even though a DTO </p> <blockquote> <p> "is one of those objects our mothers told us never to write." </p> <footer><cite>Marin Fowler, <a href="/ref/peaa">Patterns of Enterprise Application Architecture</a></cite></footer> </blockquote> <p> We almost have to do violence to ourselves to introduce a DTO in an object-oriented code base, yet grudgingly we accept that this is probably better than the alternative. </p> <p> In FP, on the other hand, that's just natural. </p> <p> To paraphrase the simple example from the old article, imagine that you receive data like this as input: </p> <p> <pre>{ &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;firstName&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Mark&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;lastName&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Seemann&quot;</span> }</pre> </p> <p> If we wanted to capture that structure as a type, in <a href="https://fsharp.org">F#</a> you'd write a type like this: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;Name&nbsp;=&nbsp;{&nbsp;FirstName&nbsp;:&nbsp;string;&nbsp;LastName&nbsp;:&nbsp;string&nbsp;}</pre> </p> <p> And while you might feel icky defining such a DTO-like type in OOP, it's perfectly natural and expected in FP. </p> <p> That type even supports JSON serialization and deserialization without further <a href="/2019/12/16/zone-of-ceremony">ceremony</a>: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;opts&nbsp;=&nbsp;JsonSerializerOptions&nbsp;(PropertyNamingPolicy&nbsp;=&nbsp;JsonNamingPolicy.CamelCase) <span style="color:blue;">let</span>&nbsp;n&nbsp;=&nbsp;JsonSerializer.Deserialize&lt;Name&gt;&nbsp;(json,&nbsp;opts)</pre> </p> <p> where <code>json</code> might contain the above JSON fragment. </p> <p> To summarise so far: <em>Data crosses the boundaries of systems - not objects</em>. Since FP tends to separate data from behaviour, that paradigm feels more natural in that context. </p> <h3 id="3f60d44d38f24e8080eb4d8123ed5530"> Not all peaches and cream <a href="#3f60d44d38f24e8080eb4d8123ed5530" title="permalink">#</a> </h3> <p> FP is, however, not a perfect fit either. Let's paraphrase the above medial summary: <em>Data crosses the boundaries of systems - not functions</em>. </p> <p> FP is more than just functions <em>and</em> data. It's also about functions as first-class concepts, including functions as values, and <a href="https://en.wikipedia.org/wiki/Higher-order_function">higher-order functions</a>. While an object is <em>data with behaviour</em>, <a href="/2018/02/12/object-isomorphisms">closures <em>are behaviour with data</em></a>. Such first-class values cross system boundaries with the same ease as objects do: Not very well. </p> <p> I was recently helping a client defining a domain-specific language (DSL). I wrote a proof of concept in <a href="https://www.haskell.org">Haskell</a> based on Abstract Syntax Trees (AST). Each AST would typically be defined with copious use of lambda expressions. There was also an existential type involved. </p> <p> At one time, the question of persistence came up. At first I thought that you could easily serialize those ASTs, since, after all, they're just immutable values. Then I realised that while that's true, most of the constituent values were <em>functions</em>. There's no clear way to serialize a function, other than in code. </p> <p> Functions don't easily cross boundaries, for the same reasons that objects don't. </p> <p> So while FP seems like a better fit when it comes to modelling data, <em>at the boundaries, applications aren't functional</em>. </p> <h3 id="7ab8590765114bcf91c0e505e6b34271"> Weak or strong typing? <a href="#7ab8590765114bcf91c0e505e6b34271" title="permalink">#</a> </h3> <p> In my original article, I attempted to look ahead. One option I considered was dynamic typing. Instead of defining a DTO that mirrors a particular shape of data (e.g. a JSON document), would it be easier to parse or create a document on the fly, without a static type? </p> <p> I occasionally find myself doing that, as you can see in my article <a href="/2022/01/03/to-id-or-not-to-id">To ID or not to ID</a>. The code base already used <a href="https://www.newtonsoft.com/json">Json.NET</a>, and I found it easier to use the <code>JToken</code> API to parse documents, rather than having to maintain a static type whose only raison d'être was to mirror a JSON document. I repeat an example here for your convenience: </p> <p> <pre><span style="color:green;">//&nbsp;JToken&nbsp;-&gt;&nbsp;UserData&lt;string&gt;</span> <span style="color:blue;">let</span>&nbsp;<span style="color:blue;">private</span>&nbsp;parseUser&nbsp;(jobj&nbsp;:&nbsp;JToken)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;uid&nbsp;=&nbsp;jobj.[<span style="color:#a31515;">&quot;id&quot;</span>]&nbsp;|&gt;&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;fn&nbsp;=&nbsp;jobj.[<span style="color:#a31515;">&quot;firstName&quot;</span>]&nbsp;|&gt;&nbsp;Option.ofObj&nbsp;|&gt;&nbsp;Option.map&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;ln&nbsp;=&nbsp;jobj.[<span style="color:#a31515;">&quot;lastName&quot;</span>]&nbsp;|&gt;&nbsp;Option.ofObj&nbsp;|&gt;&nbsp;Option.map&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;email&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jobj.[<span style="color:#a31515;">&quot;primaryEmail&quot;</span>] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.ofObj &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.map&nbsp;(string&nbsp;&gt;&gt;&nbsp;MailAddress) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;uid &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FirstName&nbsp;=&nbsp;fn &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LastName&nbsp;=&nbsp;ln &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;email &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Identities&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permissions&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;}</pre> </p> <p> Likewise, I also used <code>JObject</code> to create and serialize new JSON documents. The <em>To ID or not to ID</em> article also contains an example of that. </p> <p> F# types are typically one-liners, like that above <code>Name</code> example. If that's true, why do I shy away from defining a static type that mirrors the desired JSON document structure? </p> <p> Because <a href="/2018/09/17/typing-is-not-a-programming-bottleneck">typing (the other kind of typing) isn't a programming bottleneck</a>. The cost of another type isn't the time it takes to write the code. It's the maintenance burden it adds. </p> <p> One problem you'll commonly have when you define DTOs as static types is that the code base will contain more than one type that represents the same concept. If these types are too similar, it becomes difficult for programmers to distinguish between them. As a result, functionality may inadvertently be coupled to the wrong type. </p> <p> Still, there can be good reasons to introduce a DTO type and a domain model. As <a href="https://lexi-lambda.github.io/">Alexis King</a> writes, </p> <blockquote> <p> "Consider: what is a parser? Really, a parser is just a function that consumes less-structured input and produces more-structured output." </p> <footer><cite>Alexis King, <a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/">Parse, don’t validate</a></cite></footer> </blockquote> <p> This is the approach I took in <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. A <code>ReservationDto</code> class has almost no invariants. It's just a bag of mutable and nullable properties; it's less-structured data. </p> <p> The corresponding domain model <code>Reservation</code> is more-structured. It's an immutable <a href="https://martinfowler.com/bliki/ValueObject.html">Value Object</a> that guarantees various invariants: All required data is present, quantity is a natural number, you can't mutate the object, and it has structural equality. </p> <p> In that case, <code>ReservationDto</code> and <code>Reservation</code> are sufficiently different. I consider their separate roles in the code base clear and distinct. </p> <h3 id="f416242d15a24f41a925182f180b4c2e"> Conclusion <a href="#f416242d15a24f41a925182f180b4c2e" title="permalink">#</a> </h3> <p> In 2011 I observed that at the boundaries, applications aren't object-oriented. For years, I've thought it a natural corollary that likewise, <em>at the boundaries, applications aren't functional</em>, either. On the other hand, I don't think I've explicitly made that statement before. </p> <p> A decade after 2011, I still find object-oriented programming incongruent with how software must work in reality. Functional programming offers an alternative that, while also not perfectly aligned with all data, seems better aligned with the needs of working software. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. The Maybe monad https://blog.ploeh.dk/2022/04/25/the-maybe-monad 2022-04-25T06:50:00+00:00 Mark Seemann <div id="post"> <p> <em>The Maybe sum type forms a monad. An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2022/03/28/monads">an article series about monads</a>. </p> <p> The Maybe <a href="https://en.wikipedia.org/wiki/Tagged_union">sum type</a> is a useful data type that <a href="/2018/03/26/the-maybe-functor">forms a functor</a>. Like many other useful functors, it also forms a monad. </p> <p> It can be useful when querying another data structure (like a list or a tree) for a value that may or may not be present. It's also useful when performing a calculation that may not be possible, such as taking the square root of of a number, or calculating the average of a collection of values. A third common use case is when parsing a value, although usually, the Either sum type is often a better option for that task. </p> <h3 id="20497728035845fd9e7be0bb1ffae94c"> Bind <a href="#20497728035845fd9e7be0bb1ffae94c" title="permalink">#</a> </h3> <p> A monad must define either a <em>bind</em> or <em>join</em> function. In C#, monadic bind is called <code>SelectMany</code>. Depending on how you've implemented <code>Maybe&lt;T&gt;</code> the details of the implementation may vary, but the observable behaviour must always be the same. In this article I'm going to continue to use the <code>Maybe&lt;T&gt;</code> class first shown in <a href="/2018/03/26/the-maybe-functor">the article about the Maybe functor</a>. (That's not really my favourite implementation, but it doesn't matter.) </p> <p> In that code base, I chose to implement <code>SelectMany</code> as an extension method. Why I didn't use an instance method I no longer remember. Again, this doesn't matter. </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Maybe&lt;TResult&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Maybe&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Maybe&lt;TResult&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(source.HasItem) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;selector(source.Item); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;TResult&gt;(); }</pre> </p> <p> If the <code>source</code> has an item, <code>SelectMany</code> calls <code>selector</code> with the value and returns the result. If not, the result is an empty <code>Maybe&lt;TResult&gt;</code>. </p> <p> Monadic bind becomes useful when you have more than one function that returns a monadic value. Consider, for example, this variation of <code>Average</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#74531f;">Average</span>(IEnumerable&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">values</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(values.Any()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;(values.Average()); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;(); }</pre> </p> <p> You can't calculate the average of an empty collection, so if <code>values</code> is empty, this function returns an empty <code>Maybe&lt;double&gt;</code>. </p> <p> If you only needed this <code>Average</code> function, then you could use Maybe's <a href="/2018/03/22/functors">functor</a> affordance to map the result. On the other hand, imagine that you'd like to pass the <code>Average</code> result to this <code>Sqrt</code> function: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#74531f;">Sqrt</span>(<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">d</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">result</span>&nbsp;=&nbsp;Math.Sqrt(d); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">switch</span>&nbsp;(result) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">case</span>&nbsp;<span style="color:blue;">double</span>.NaN: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">case</span>&nbsp;<span style="color:blue;">double</span>.PositiveInfinity:&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">default</span>:&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;(result); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This is another calculation that may not be possible. If you try to compose <code>Average</code> and <code>Sqrt</code> with <code>Select</code> (the functor's <em>map</em> function), you'd get a <code>Maybe&lt;Maybe&lt;double&gt;&gt;</code>. Fortunately, however, monads are functors you can flatten: </p> <p> <pre>[Theory] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[0],&nbsp;-100)] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[]&nbsp;{&nbsp;5,&nbsp;3&nbsp;},&nbsp;2)] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[]&nbsp;{&nbsp;1,&nbsp;-2&nbsp;},&nbsp;-100)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ComposeAverageAndSqrt</span>(<span style="color:blue;">double</span>[]&nbsp;<span style="color:#1f377f;">values</span>,&nbsp;<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;Average(values).SelectMany(Sqrt); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;actual.GetValueOrFallback(-100)); }</pre> </p> <p> The <code>SelectMany</code> method flattens as it goes. Viewed in this way, <a href="https://www.scala-lang.org/">Scala</a>'s <code>flatMap</code> seems like a more appropriate name. </p> <p> The above test demonstrates how <code>SelectMany</code> returns a flattened <code>Maybe&lt;double&gt;</code>. The first test case has zero elements, so the <code>Average</code> method is going to return an empty <code>Maybe&lt;double&gt;</code>. <code>SelectMany</code> handles that gracefully by returning another empty value. </p> <p> In the second test case <code>Average</code> returns a populated value that contains the number <code>4</code>. <code>SelectMany</code> passes <code>4</code> to <code>Sqrt</code>, which returns <code>2</code> wrapped in a <code>Maybe&lt;double&gt;</code>. </p> <p> In the third test case, the average is <code>-.5</code>, wrapped in a <code>Maybe&lt;double&gt;</code>. <code>SelectMany</code> passes <code>-.5</code> on to <code>Sqrt</code>, which returns an empty value. </p> <h3 id="c9bb381e6f834ba2b955e3ea13efba7d"> Query syntax <a href="#c9bb381e6f834ba2b955e3ea13efba7d" title="permalink">#</a> </h3> <p> Monads also enable query syntax in C# (just like they enable other kinds of syntactic sugar in languages like <a href="https://fsharp.org">F#</a> and <a href="https://www.haskell.org">Haskell</a>). As outlined in the <a href="/2022/03/28/monads">monad introduction</a>, however, you must add a special <code>SelectMany</code> overload: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Maybe&lt;TResult&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">U</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Maybe&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Maybe&lt;U&gt;&gt;&nbsp;<span style="color:#1f377f;">k</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;U,&nbsp;TResult&gt;&nbsp;<span style="color:#1f377f;">s</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;k(x).Select(<span style="color:#1f377f;">y</span>&nbsp;=&gt;&nbsp;s(x,&nbsp;y))); }</pre> </p> <p> As I also mentioned in the monad introduction, it seems to me that you can always implement this overload with the above expression. Once this overload is in place, you can rewrite the above composition in query syntax, if that's more to your liking: </p> <p> <pre>[Theory] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[0],&nbsp;-100)] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[]&nbsp;{&nbsp;5,&nbsp;3&nbsp;},&nbsp;2)] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[]&nbsp;{&nbsp;1,&nbsp;-2&nbsp;},&nbsp;-100)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ComposeAverageAndSqrtWithQuerySyntax</span>(<span style="color:blue;">double</span>[]&nbsp;<span style="color:#1f377f;">values</span>,&nbsp;<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;a&nbsp;<span style="color:blue;">in</span>&nbsp;Average(values) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;s&nbsp;<span style="color:blue;">in</span>&nbsp;Sqrt(a) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;s; &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;actual.GetValueOrFallback(-100)); }</pre> </p> <p> In this case, query syntax is more verbose, but the behaviour is the same. It's just two different ways of writing the same expression. The C# compiler desugars the query-syntax expression to one that composes with <code>SelectMany</code>. </p> <h3 id="09cb0abf4e7d4c21bce8796a57a5df50"> Join <a href="#09cb0abf4e7d4c21bce8796a57a5df50" title="permalink">#</a> </h3> <p> In <a href="/2022/03/28/monads">the introduction</a> you learned that if you have a <code>Flatten</code> or <code>Join</code> function, you can implement <code>SelectMany</code>, and the other way around. Since we've already defined <code>SelectMany</code> for <code>Maybe&lt;T&gt;</code>, we can use that to implement <code>Join</code>. In this article I use the name <code>Join</code> rather than <code>Flatten</code>. This is an arbitrary choice that doesn't impact behaviour. Perhaps you find it confusing that I'm inconsistent, but I do it in order to demonstrate that the behaviour is the same even if the name is different. </p> <p> The concept of a monad is universal, but the names used to describe its components differ from language to language. What C# calls <code>SelectMany</code>, Scala calls <code>flatMap</code>, and what Haskell calls <code>join</code>, other languages may call <code>Flatten</code>. </p> <p> You can always implement <code>Join</code> by using <code>SelectMany</code> with the identity function. </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Maybe&lt;T&gt;&nbsp;<span style="color:#74531f;">Join</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;Maybe&lt;Maybe&lt;T&gt;&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x); }</pre> </p> <p> Instead of flattening as you go with <code>SelectMany</code>, you could also use <code>Select</code> and <code>Join</code> to compose <code>Average</code> and <code>Sqrt</code>: </p> <p> <pre>[Theory] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[0],&nbsp;-100)] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[]&nbsp;{&nbsp;5,&nbsp;3&nbsp;},&nbsp;2)] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">double</span>[]&nbsp;{&nbsp;1,&nbsp;-2&nbsp;},&nbsp;-100)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">JoinAverageAndSqrt</span>(<span style="color:blue;">double</span>[]&nbsp;<span style="color:#1f377f;">values</span>,&nbsp;<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;Average(values).Select(Sqrt).Join(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;actual.GetValueOrFallback(-100)); }</pre> </p> <p> You'd typically not write the composition like this, as it seems more convenient to use <code>SelectMany</code>, but you could. The behaviour is the same. </p> <h3 id="770215f4b3da49dd976dc67e2416481e"> Return <a href="#770215f4b3da49dd976dc67e2416481e" title="permalink">#</a> </h3> <p> Apart from monadic bind, a monad must also define a way to put a normal value into the monad. Conceptually, I call this function <em>return</em> (because that's the name that Haskell uses). You don't, however, have to define a static method called <code>Return</code>. What's of importance is that the capability exists. For <code>Maybe&lt;T&gt;</code> in C# the <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a> way would be to use a constructor. This constructor overload does double duty as monadic <em>return</em>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Maybe</span>(T&nbsp;<span style="color:#1f377f;">item</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(item&nbsp;==&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(item)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.HasItem&nbsp;=&nbsp;<span style="color:blue;">true</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.Item&nbsp;=&nbsp;item; }</pre> </p> <p> Why is it that overload, and not the other one? Because if you try to use <code>new Maybe&lt;T&gt;()</code> as <em>return</em>, you'll find that it breaks the <a href="/2022/04/11/monad-laws">monad laws</a>. Try it. It's a good exercise. </p> <h3 id="393bd508a0b549ca908c8950589bd910"> Left identity <a href="#393bd508a0b549ca908c8950589bd910" title="permalink">#</a> </h3> <p> Now that we're on the topic of the monad laws, let's see what they look like for the Maybe monad, starting with the left identity law. </p> <p> <pre>[Theory] [InlineData(0)] [InlineData(1)] [InlineData(2)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">LeftIdentity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;(i); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;i&nbsp;!=&nbsp;0&nbsp;?&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;(1&nbsp;/&nbsp;i)&nbsp;:&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(@return(a).SelectMany(h),&nbsp;h(a)); }</pre> </p> <p> To provide some variety, <code>h</code> is another Maybe-valued function - this time one that performs a safe <a href="https://en.wikipedia.org/wiki/Multiplicative_inverse">multiplicative inverse</a>. If <code>i</code> is zero, it returns an empty <code>Maybe&lt;double&gt;</code> because you can't devide by zero; otherwise, it returns one divided by <code>i</code> (wrapped in a <code>Maybe&lt;double&gt;</code>). </p> <h3 id="fcd0a8fe00784ec1a606d867fbc52384"> Right identity <a href="#fcd0a8fe00784ec1a606d867fbc52384" title="permalink">#</a> </h3> <p> In a similar manner, we can showcase the right identity law as a test. </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;42&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;1337&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">RightIdentity</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#74531f;">f</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(<span style="color:blue;">int</span>.TryParse(s,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">i</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;(i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;(i); &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(@return),&nbsp;m); }</pre> </p> <p> Again, for variety's sake, for <code>f</code> I've chosen a function that should probably be named <code>TryParseInt</code> if used in another context. </p> <h3 id="52f8e7ce874942d2999e647c3a354869"> Associativity <a href="#52f8e7ce874942d2999e647c3a354869" title="permalink">#</a> </h3> <p> The last monad law is the associativity law that we can demonstrate like this: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;-1&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;0&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;4&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Associativity</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#74531f;">f</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(<span style="color:blue;">int</span>.TryParse(s,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">i</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;(i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">int</span>&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Sqrt(i); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;d&nbsp;==&nbsp;0&nbsp;?&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;()&nbsp;:&nbsp;<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">double</span>&gt;(1&nbsp;/&nbsp;2); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(g).SelectMany(h),&nbsp;m.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h))); }</pre> </p> <p> Here, I've copy-and-pasted the <em>TryParseInt</em> function I also used in the right identity example, and combined it with the <code>Sqrt</code> function and a safe multiplicative inverse. The law, however, should hold for all <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a> that type-check. The functions shown here are just examples. </p> <p> As usual, a parametrised test is no proof that the law holds. I provide the tests only as examples of what the laws looks like. </p> <h3 id="7a49fae4e6fc4ba3850c323cf22d62f6"> Conclusion <a href="#7a49fae4e6fc4ba3850c323cf22d62f6" title="permalink">#</a> </h3> <p> The Maybe sum type is a versatile and useful data structure that forms a monad. This enables you to compose disparate functions that each may err by failing to return a value. </p> <p> <strong>Next: </strong> <a href="/2022/05/09/an-either-monad">An Either monad</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. The List monad https://blog.ploeh.dk/2022/04/19/the-list-monad 2022-04-19T05:45:00+00:00 Mark Seemann <div id="post"> <p> <em>Lists, collections, deterministic Iterators form a monad. An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2022/03/28/monads">an article series about monads</a>. </p> <p> In the article series about <a href="/2018/03/22/functors">functors</a> I never included an explicit article about collections. Instead, I wrote: </p> <blockquote> <p> "Perhaps the most well-known of all functors is List, a.k.a. Sequence. C# query syntax can handle any functor, but most people only think of it as a language feature related to <code>IEnumerable&lt;T&gt;</code>. Since the combination of <code>IEnumerable&lt;T&gt;</code> and query syntax is already well-described, I'm not going to cover it explicitly here." </p> <footer><cite><a href="/2018/03/22/functors">Functors</a>, Mark Seemann, 2018</cite></footer> </blockquote> <p> Like many other useful functors, a list also forms a monad. In this article, I call it <em>list</em>. In <a href="https://www.haskell.org">Haskell</a> the most readily available equivalent is the built-in linked list (<code>[]</code>). Likewise, in <a href="https://fsharp.org">F#</a>, the fundamental collection types are linked lists and arrays. In C#, any <code>IEnumerable&lt;T&gt;</code> forms a monad. The .NET <code>IEnumerable&lt;T&gt;</code> interface is an application of the <a href="https://en.wikipedia.org/wiki/Iterator_pattern">Iterator design pattern</a>. There are many possible names for this monad: <em>list</em>, <em>sequence</em>, <em>collection</em>, <em>iterator</em>, etcetera. I've arbitrarily chosen to mostly use <em>list</em>. </p> <h3 id="13be436e595c411baf581dcfb31ab86f"> SelectMany <a href="#13be436e595c411baf581dcfb31ab86f" title="permalink">#</a> </h3> <p> In the <a href="/2022/03/28/monads">introduction to monads</a> you learned that monads are characterised by having either a <em>join</em> (or <em>flatten</em>) function, or a <em>bind</em> function. While in Haskell, monadic bind is the <code>&gt;&gt;=</code> operator, in C# it's a method called <code>SelectMany</code>. Perhaps you wonder about the name. </p> <p> The name <code>SelectMany</code> makes most sense in the context of lists. An example would be useful around here. </p> <p> Imagine that you have to parse a <a href="https://en.wikipedia.org/wiki/Comma-separated_values">CSV</a> file. You've already read the file from disc and split the contents into lines. Now you need to split each line on commas. </p> <p> <pre>&gt; <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">lines</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;foo,bar,baz&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;qux,quux,quuz&quot;</span>&nbsp;}; &gt; lines.Select(l =&gt; l.Split(',')).ToArray() string[2][] { string[3] { "foo", "bar", "baz" }, string[3] { "qux", "quux", "quuz" } }</pre> </p> <p> When you use <code>Select</code> the result is a nested list. You've already learned that a monad is a functor you can flatten. In C#, you can 'flatten as you go' with <code>SelectMany</code>. </p> <p> The above scenario offers a hint at why the method is named <code>SelectMany</code>. You use it instead of <code>Select</code> when the selector returns <em>many</em> values. In the above example, the <code>Split</code> method returns many values. </p> <p> So, instead of <code>Select</code>, use <code>SelectMany</code> if you need a flattened list: </p> <p> <pre>&gt; lines.SelectMany(l =&gt; l.Split(',')).ToArray() string[6] { "foo", "bar", "baz", "qux", "quux", "quuz" }</pre> </p> <p> I've never had the opportunity to ask any of the LINQ designers about that naming choice, but this explanation makes sense to me. Even if it turns out that they had something else in mind when they named the method, I think that my explanation at least serves as a mnemonic device. </p> <p> The name is still unfortunate, since it mostly makes sense for the list monad. Already when you use <code>SelectMany</code> with the Maybe monad, the name makes less sense. </p> <h3 id="4f2a54b64a744c5f855c2baa9f1c8d9a"> Flatten <a href="#4f2a54b64a744c5f855c2baa9f1c8d9a" title="permalink">#</a> </h3> <p> In <a href="/2022/03/28/monads">the introduction</a> you learned that if you have a <code>Flatten</code> or <code>Join</code> function, you can implement <code>SelectMany</code>, and the other way around. In C#, LINQ already comes with <code>SelectMany</code>, but surprisingly, <code>Flatten</code> isn't built in. </p> <p> You can always implement <code>Flatten</code> by using <code>SelectMany</code> with the identity function. </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEnumerable&lt;T&gt;&nbsp;<span style="color:#74531f;">Flatten</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;IEnumerable&lt;IEnumerable&lt;T&gt;&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x); }</pre> </p> <p> Recall that the <code>selector</code> passed to <code>SelectMany</code> must have the type <code>Func&lt;TSource,&nbsp;IEnumerable&lt;TResult&gt;&gt;</code>. There's no rule, however, that says that <code>TSource</code> can't be <code>IEnumerable&lt;TResult&gt;</code>. If <code>x</code> in <code>x =&gt; x</code> has the type <code>IEnumerable&lt;TResult&gt;</code>, then <code>x =&gt; x</code> has the type <code>Func&lt;IEnumerable&lt;TResult&gt;,&nbsp;IEnumerable&lt;TResult&gt;&gt;</code> and it all type-checks. </p> <p> Here's a test that demonstrates how <code>Flatten</code> works: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FlattenExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>[][]&nbsp;<span style="color:#1f377f;">nested</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>&nbsp;},&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;baz&quot;</span>&nbsp;}&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">flattened</span>&nbsp;=&nbsp;nested.Flatten(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;baz&quot;</span>&nbsp;},&nbsp;flattened); }</pre> </p> <p> In Haskell <code>Flatten</code> is called <code>join</code> and is implemented this way: </p> <p> <pre>join :: (Monad m) =&gt; m (m a) -&gt; m a join x = x &gt;&gt;= id</pre> </p> <p> It's the same implementation as the above C# method: monadic bind (<code>SelectMany</code> in C#; <code>&gt;&gt;=</code> in Haskell) with the identity function. The Haskell implementation works for all monads. </p> <h3 id="f54cad2a32b341e1a11420fe53c0a7e1"> Return <a href="#f54cad2a32b341e1a11420fe53c0a7e1" title="permalink">#</a> </h3> <p> Apart from monadic bind, a monad must also define a way to put a normal value into the monad. For the list monad, this implies a single value promoted to a list. Surprisingly, the .NET base class library doesn't come with such a built-in function, but you can easily implement it yourself: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEnumerable&lt;T&gt;&nbsp;<span style="color:#74531f;">Return</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;x; }</pre> </p> <p> In practice, however, you'd normally instead create a singleton array, like this: <code>new[] { 2112 }</code>. Since arrays implement <code>IEnumerable&lt;T&gt;</code>, this works just as well. </p> <p> Why is this the correct implementation of <em>return?</em> </p> <p> Wouldn't this work? </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEnumerable&lt;T&gt;&nbsp;<span style="color:#74531f;">ReturnZero</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">break</span>; }</pre> </p> <p> Or this? </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEnumerable&lt;T&gt;&nbsp;<span style="color:#74531f;">ReturnTwo</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;x; }</pre> </p> <p> None of these are appropriate because they break the <a href="/2022/04/11/monad-laws">monad laws</a>. Try it, as an exercise! </p> <h3 id="0795515a923a47ad95417dc77a826c24"> Left identity <a href="#0795515a923a47ad95417dc77a826c24" title="permalink">#</a> </h3> <p> Now that we're on the topic of the monad laws, let's see what they look like for the list monad, starting with the left identity law. </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo,bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo,bar,baz&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">LeftIdentity</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;List.Return; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Split(<span style="color:#a31515;">&#39;,&#39;</span>); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(@return(a).SelectMany(h),&nbsp;h(a)); }</pre> </p> <p> As usual, a parametrised test is no proof that the law holds. I provide it only as an example of what the law looks like. </p> <h3 id="09b17be2537842a3994b697e723ada34"> Right identity <a href="#09b17be2537842a3994b697e723ada34" title="permalink">#</a> </h3> <p> Likewise, we can showcase the right identity law as a test: </p> <p> <pre>[Theory] [InlineData(0)] [InlineData(1)] [InlineData(9)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">RightIdentity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Enumerable.Repeat(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;i); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;List.Return; &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(@return),&nbsp;m); }</pre> </p> <p> These tests all pass. </p> <h3 id="c8898fa040ce4c138c0beadbf5a045d0"> Associativity <a href="#c8898fa040ce4c138c0beadbf5a045d0" title="permalink">#</a> </h3> <p> The last monad law is the associativity law that we can demonstrate like this: </p> <p> <pre>[Theory] [InlineData(0)] [InlineData(3)] [InlineData(8)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Associativity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Enumerable.Repeat(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;i); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IEnumerable&lt;<span style="color:blue;">char</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">char</span>,&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">c</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;c.ToString().ToUpper(),&nbsp;c.ToString().ToLower()&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(g).SelectMany(h),&nbsp;m.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h))); }</pre> </p> <p> The three functions <code>f</code>, <code>g</code>, and <code>h</code> are just silly functions I chose for variety's sake. </p> <h3 id="e15e1dfc86b94747ab7f7dc66faa02d2"> Conclusion <a href="#e15e1dfc86b94747ab7f7dc66faa02d2" title="permalink">#</a> </h3> <p> Lists, arrays, collections, Iterators are various names for a common idea: that of an ordered sequence of values. In this article, I've called it <em>list</em> for simplicity's sake. It's possible to flatten nested lists in a well-behaved manner, which makes <em>list</em> a monad. </p> <p> <strong>Next:</strong> <a href="/2022/04/25/the-maybe-monad">The Maybe monad</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Monad laws https://blog.ploeh.dk/2022/04/11/monad-laws 2022-04-11T06:57:00+00:00 Mark Seemann <div id="post"> <p> <em>An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2022/03/28/monads">an article series about monads</a>. </p> <p> Just as <a href="/2018/03/22/functors">functors</a> must obey the functor laws, monads must follow the monad laws. When looked at from the right angle, these are intuitive and reasonable rules: <a href="https://en.wikipedia.org/wiki/Identity_element">identity</a> and <a href="https://en.wikipedia.org/wiki/Associative_property">associativity</a>. </p> <p> That sounds almost like a <a href="/2017/10/06/monoids">monoid</a>, but the rules are more relaxed. For monoids, we require a <a href="https://en.wikipedia.org/wiki/Binary_operation">binary operation</a>. That's not the case for functors and monads. Instead of binary operations, for monads we're going to use <a href="/2022/04/04/kleisli-composition">Kleisli composition</a>. </p> <p> This article draws heavily on the <a href="https://wiki.haskell.org/Monad_laws">Haskell wiki on monad laws</a>. </p> <p> In short, the monad laws comprise three rules: </p> <ul> <li>Left identity</li> <li>Right identity</li> <li>Associativity</li> </ul> <p> The article describes each in turn, starting with left identity. </p> <h3 id="2589cde8994b4e3db81ef821d8f346ba"> Left identity <a href="#2589cde8994b4e3db81ef821d8f346ba" title="permalink">#</a> </h3> <p> A left identity is an element that, when applied to the left of an operator, doesn't change the other element. When used with the <a href="/2022/04/04/kleisli-composition">fish operator</a> it looks like this: </p> <p> <pre>id &gt;=&gt; h ≡ h</pre> </p> <p> For monads, <code>id</code> turns out to be <code>return</code>, so more specifically: </p> <p> <pre>return &gt;=&gt; h ≡ h</pre> </p> <p> In C# we can illustrate the law as a parametrised test: </p> <p> <pre>[Theory] [InlineData(-1)] [InlineData(42)] [InlineData(87)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">LeftIdentityKleisli</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Monad.Return; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Monad.Return(i.ToString()); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">composed</span>&nbsp;=&nbsp;@return.Compose(h); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(composed(a),&nbsp;h(a)); }</pre> </p> <p> Recall that we can implement the fish operators as <code>Compose</code> overloads. The above test demonstrates the notion that <code>@return</code> composed with <code>h</code> should be indistinguishable from <code>h</code>. Such a test should pass. </p> <p> Keep in mind, however, that Kleisli composition is <em>derived</em> from the definition of a monad. The direct definition of monads is that they come with a <code>return</code> and <code>bind</code> functions (or, alternatively <code>return</code> and <code>join</code>). If we <a href="https://refactoring.com/catalog/inlineFunction.html">inline</a> the implementation of <code>Compose</code>, the test instead looks like this: </p> <p> <pre>[Theory] [InlineData(-1)] [InlineData(42)] [InlineData(87)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">LeftIdentityInlined</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Monad.Return; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Monad.Return(i.ToString()); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">composed</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;@return(x).SelectMany(h); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(composed(a),&nbsp;h(a)); }</pre> </p> <p> or, more succinctly: </p> <p> <pre>Assert.Equal(@return(a).SelectMany(h),&nbsp;h(a));</pre> </p> <p> This is also the way the left identity law is usually presented in <a href="https://www.haskell.org">Haskell</a>: </p> <p> <pre>return a &gt;&gt;= h = h a</pre> </p> <p> In Haskell, <em>monadic bind</em> is represented by the <code>&gt;&gt;=</code> operator, while in C# it's the <code>SelectMany</code> method. Thus, the Haskell and the C# representations are equivalent. </p> <h3 id="b74cccb66945471d8b28e40e4e90516d"> Right identity <a href="#b74cccb66945471d8b28e40e4e90516d" title="permalink">#</a> </h3> <p> Right identity starts out similar to left identity. Using the fish operator, the Haskell wiki describes it as: </p> <p> <pre>f &gt;=&gt; return ≡ f</pre> </p> <p> Translated to a C# test, an example of that law might look like this: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;ploeh&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;lawful&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">RightIdentityKleisli</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Monad.Return(s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Monad.Return; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">composed</span>&nbsp;=&nbsp;f.Compose(@return); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(composed(a),&nbsp;f(a)); }</pre> </p> <p> Again, if we inline <code>Compose</code>, the test instead looks like this: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;ploeh&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;lawful&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">RightIdentityInlined</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Monad.Return(s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Monad.Return; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">composed</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;f(x).SelectMany(@return); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(composed(a),&nbsp;f(a)); }</pre> </p> <p> Now explicitly call the <code>f</code> function and assign it to a variable <code>m</code>: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;ploeh&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;lawful&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">RightIdentityInlinedIntoAssertion</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Monad.Return(s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Monad.Return; &nbsp;&nbsp;&nbsp;&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(@return),&nbsp;m); }</pre> </p> <p> The assertion is now the C# version of the normal Haskell definition of the right identity law: </p> <p> <pre>m &gt;&gt;= return = m</pre> </p> <p> In other words, <code>return</code> is the identity element for monadic composition. It doesn't really 'do' anything in itself. </p> <h3 id="3d323da500cc4405ac4768b1108cfdf9"> Associativity <a href="#3d323da500cc4405ac4768b1108cfdf9" title="permalink">#</a> </h3> <p> The third monad law is the associativity law. Keep in mind that an operator like <code>+</code> is associative if it's true that </p> <p> <pre>(x + y) + z = x + (y + z)</pre> </p> <p> Instead of <code>+</code>, the operator in question is the fish operator, and since values are functions, we typically call them <code>f</code>, <code>g</code>, and <code>h</code> rather than <code>x</code>, <code>y</code>, and <code>z</code>: </p> <p> <pre>(f &gt;=&gt; g) &gt;=&gt; h ≡ f &gt;=&gt; (g &gt;=&gt; h)</pre> </p> <p> Translated to a C# test as an example, the law looks like this: </p> <p> <pre>[Theory] [InlineData(0)] [InlineData(1)] [InlineData(2)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">AssociativityKleisli</span>(<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Monad&lt;<span style="color:blue;">bool</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Monad.Return(i&nbsp;%&nbsp;2&nbsp;==&nbsp;0); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">bool</span>,&nbsp;Monad&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">b</span>&nbsp;=&gt;&nbsp;Monad.Return(b.ToString()); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Monad.Return(s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">left</span>&nbsp;=&nbsp;(f.Compose(g)).Compose(h); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">right</span>&nbsp;=&nbsp;f.Compose(g.Compose(h)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(left(a),&nbsp;right(a)); }</pre> </p> <p> The outer brackets around <code>(f.Compose(g))</code> are actually redundant; we should remove them. Also, inline <code>Compose</code>: </p> <p> <pre>[Theory] [InlineData(0)] [InlineData(1)] [InlineData(2)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">AssociativityInlined</span>(<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Monad&lt;<span style="color:blue;">bool</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Monad.Return(i&nbsp;%&nbsp;2&nbsp;==&nbsp;0); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">bool</span>,&nbsp;Monad&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">b</span>&nbsp;=&gt;&nbsp;Monad.Return(b.ToString()); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Monad.Return(s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Monad&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">fg</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;f(x).SelectMany(g); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">left</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;fg(x).SelectMany(h); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">bool</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">gh</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">right</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;f(x).SelectMany(gh); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(left(a),&nbsp;right(a)); }</pre> </p> <p> If there's a way in C# to inline the local compositions <code>fg</code> and <code>gh</code> directly into <code>left</code> and <code>right</code>, respectively, I don't know how. In any case, the above is just an intermediate step. </p> <p> For both <code>left</code> and <code>right</code>, notice that the first step involves invoking <code>f</code> with <code>x</code>. If, instead, we call that value <code>m</code>, we can rewrite the test like this: </p> <p> <pre>[Theory] [InlineData(0)] [InlineData(1)] [InlineData(2)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">AssociativityInlinedIntoAssertion</span>(<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;Monad&lt;<span style="color:blue;">bool</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Monad.Return(i&nbsp;%&nbsp;2&nbsp;==&nbsp;0); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">bool</span>,&nbsp;Monad&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">b</span>&nbsp;=&gt;&nbsp;Monad.Return(b.ToString()); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Monad.Return(s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Monad&lt;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(g).SelectMany(h),&nbsp;m.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h))); }</pre> </p> <p> The above assertion corresponds to the way the associativity law is usually represented in Haskell: </p> <p> <pre>(m &gt;&gt;= g) &gt;&gt;= h = m &gt;&gt;= (\x -&gt; g x &gt;&gt;= h)</pre> </p> <p> Once more, keep in mind that <code>&gt;&gt;=</code> in Haskell corresponds to <code>SelectMany</code> in C#. </p> <h3 id="d43cb529320e4dc2ab2003e68918ae92"> Conclusion <a href="#d43cb529320e4dc2ab2003e68918ae92" title="permalink">#</a> </h3> <p> A proper monad must satisfy the three monad laws: left identity, right identity, and associativity. Together, left identity and right identity are know as simply <em>identity</em>. What's so special about identity and associativity? </p> <p> As <a href="https://bartoszmilewski.com/2014/11/04/category-the-essence-of-composition/">Bartosz Milewski explains</a>, a <em>category</em> must satisfy associativity and identity. When it comes to monads, the category in question is the <a href="https://bartoszmilewski.com/2014/12/23/kleisli-categories/">Kleisli category</a>. Or, as the Haskell wiki puts it: </p> <blockquote> <p>Monad axioms:<br/> Kleisli composition forms<br/> a category.</p> <footer><cite><a href="https://wiki.haskell.org/Monad_laws">Haskell wiki</a></cite></footer> </blockquote> <p> Subsequent articles in this article series will now proceed to give examples of concrete monads, and what the laws look like for each of these. </p> <p> <strong>Next:</strong> <a href="/2022/04/19/the-list-monad">The List monad</a>. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="8e777ae4b3c64f5ab244b0e4d0f0d263"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <blockquote> That sounds almost like a <a href="/2017/10/06/monoids">monoid</a>, but the rules are more relaxed. For monoids, we require a <a href="https://en.wikipedia.org/wiki/Binary_operation">binary operation</a>. That's not the case for functors and monads. Instead of binary operations, for monads we're going to use <a href="/2022/04/04/kleisli-composition">Kleisli composition</a>. </blockquote> <p> I am confused by this paragraph. A monoid requries a binary operation (that is also closed), and Kleisli composition is (closed) binary operation. </p> <p> As you said in the <a href="https://blog.ploeh.dk/2022/03/28/monads/">introductory article to this monad series</a>, there are three pieces to a monad: a generic type <code>M&lt;&gt;</code>, a function with type <code>a -&gt; M&lt;a&gt;</code> (typically called "return"), and a function with signature <code>(a -&gt; M&lt;b&gt;) -&gt; M&lt;a&gt; -&gt; M&lt;b&gt;</code> (sometimes called "bind"). Then <code>(M&lt;&gt;, return, bind)</code> is a monad if those three items satisfy the monad laws. </p> <p> I think the following is true. Let <code>M&lt;&gt;</code> be a generic type, and let <code>S</code> be the set of all functions with signature <code>a -&gt; M&lt;a&gt;</code>. Then <code>(M&lt;&gt;, return, bind)</code> is a monad if only only if <code>(S, &gt;=&gt;, return)</code> is a monoid. </p> </div> <div class="comment-date">2022-04-18 16:17 UTC</div> </div> <div class="comment" id="2bf9e517fa744a89928ae3d9f08fedd2"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tyson, thank you for writing. To address the elephant in the room first: A monad <em>is</em> a monoid (<a href="https://bartoszmilewski.com/2016/12/27/monads-categorically/">in the category of endofunctors</a>), but as far as I can tell, you have to look more abstractly at it than allowed by the static type systems we normally employ. </p> <p> <a href="https://bartoszmilewski.com/2016/12/27/monads-categorically/">Bartosz Milewski describes</a> a <a href="/2022/03/28/monads">nested functor</a> as the tensor product of two monadic types: <code>M ⊗ M</code>. The binary operation in question is then <code>M ⊗ M -> M</code>, or <em>join/flatten</em> (from here on just <em>join</em>). In this very abstract view, monads <em>are</em> monoids. It does require an abstract view of functors as objects in a category. At that level of abstraction, so many details are lost that <em>join</em> looks like a binary operation. </p> <p> So, to be clear, if you want to look at a monad as a monoid, it's not the monadic <em>bind</em> function that's the binary operation; it's <em>join</em>. (That's another reason I prefer explaining monads in terms of <em>join</em> rather than leading with <em>bind</em>.) </p> <p> When you zoom in on the details, however, <a href="https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:join">join</a> doesn't look like a regular binary operation: <code>m (m a) -&gt; m a</code>. A binary operation, on the other hand, should look like this: <code>m a -&gt; m a -&gt; m a</code>. </p> <p> The Kleisli composition operator unfortunately doesn't fix this. Let's look at the C# method signature, since it may offer a way out: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;T,&nbsp;Monad&lt;T2&gt;&gt;&nbsp;<span style="color:#74531f;">Compose</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Monad&lt;T1&gt;&gt;&nbsp;<span style="color:#1f377f;">action1</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;Monad&lt;T2&gt;&gt;&nbsp;<span style="color:#1f377f;">action2</span>) </pre> </p> <p> Notice that the types don't match: <code>action1</code> has a type different from <code>action2</code>, which is again different from the return type. Thus, it's not a binary operation, because the elements don't belong to the same <a href="/2021/11/15/types-as-sets">set</a>. </p> <p> As Bartosz Milewski wrote, though, if we squint a little, we may make it work. C# allows us to 'squint' because of its object hierarchy: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;object,&nbsp;Monad&lt;object&gt;&gt;&nbsp;<span style="color:#74531f;">Compose</span>( &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;object,&nbsp;Monad&lt;object&gt;&gt;&nbsp;<span style="color:#1f377f;">action1</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;object,&nbsp;Monad&lt;object&gt;&gt;&nbsp;<span style="color:#1f377f;">action2</span>) </pre> </p> <p> I'm not sure how helpful that is, though, so I didn't want to get into these weeds in the above article itself. It's fine here in the comments, because I expect only very dedicated readers to consult them. This, thus, serves more like a footnote or appendix. </p> </div> <div class="comment-date">2022-04-23 11:29 UTC</div> </div> <div class="comment" id="2b7a3b85cfec410c8213adbfa3b7d33f"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <p> Thanks very much for you reply. It helped me to see where I was wrong. <code>(S, &gt;=&gt;, return)</code> is not a monoid because <code>&gt;=&gt;</code> is not total over <code>S</code>, which is another condition the binary operation must satisfy, but I overlooked that. Furthremore, I meant to define <code>S</code> as the set of all functions with signature <code>a -&gt; M&lt;b&gt;</code>. The same problem still exists though. The second code block in your comment has this same problem. There is not a natural choice for the implementation unless the types of the objects satisfy the constraints implied by the use of type parameters in the first code block in your comment. I will keep thinking about this. </p> <p> In the meantime, keep up the great work. I am loving your monad content. </p> </div> <div class="comment-date">2022-04-23 19:47 UTC</div> </div> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Kleisli composition https://blog.ploeh.dk/2022/04/04/kleisli-composition 2022-04-04T06:08:00+00:00 Mark Seemann <div id="post"> <p> <em>A way to compose two monadic functions. An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2022/03/28/monads">an article series about monads</a>. </p> <p> There's a bit of groundwork which will be useful before we get to the <a href="/2022/04/11/monad-laws">monad laws</a>. There are two ways to present the monad laws. One is quite unintuitive, but uses only the concepts already discussed in the <a href="/2022/03/28/monads">introductory article</a>. The other way to present the laws is much more intuitive, but builds on a derived concept: Kleisli composition. </p> <p> I find it preferable to take the intuitive route, even if it requires this little detour around the <a href="https://bartoszmilewski.com/2014/12/23/kleisli-categories/">Kleisli category</a>. </p> <h3 id="751e600750344be6bce3b19a3353ac9b"> Monadic functions <a href="#751e600750344be6bce3b19a3353ac9b" title="permalink">#</a> </h3> <p> Imagine some monad - any monad. It could be <em>Maybe</em> (AKA <em>Option</em>), <em>Either</em> (AKA <em>Result</em>), <em>Task</em>, <em>State</em>, etcetera. In <a href="https://www.haskell.org">Haskell</a> notation we denote it <code>m</code>. (Don't worry if you don't know Haskell. The type notation is fairly intuitive, and I'll explain enough of it along the way.) </p> <p> You may have a function that takes some input and returns a monadic value. Perhaps it's a parser that takes a string as input and returns a <em>Maybe</em> or <em>Either</em> as output: </p> <p> <pre>String -&gt; Maybe Int</pre> </p> <p> Perhaps it's a database query that takes an ID as input and returns a <em>Task</em> or <em>IO</em> value: </p> <p> <pre>UUID -&gt; IO Reservation</pre> </p> <p> Notice that in Haskell, you write the input to the left of the output. (This is also the case in <a href="https://fsharp.org/">F#</a>.) Functions looks like arrows that point from the input to the output, which is a common depiction that <a href="/2021/11/22/functions-as-pipes">I've also used before</a>. </p> <p> If we generalise this notation, we would write a monadic function like this: </p> <p> <pre>a -&gt; m b</pre> </p> <p> <code>a</code> is a generic type that denotes input. It could be <code>String</code> or <code>UUID</code> as shown above, or anything else. Likewise, <code>b</code> is another generic type that could be <code>Int</code>, <code>Reservation</code>, or anything else. And <code>m</code>, as already explained, may be any monad. The corresponding C# method signature would be: </p> <p> <pre>Func&lt;T,&nbsp;Monad&lt;T1&gt;&gt;</pre> </p> <p> In C#, it's <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a> to name generic type arguments <code>T</code> and <code>T1</code> rather than <code>a</code> and <code>b</code>, but the idea is the same. </p> <p> The previous article used <code>Functor&lt;T&gt;</code> as a stand-in for any functor. Likewise, now that you know what a monad is, the type <code>Monad&lt;T&gt;</code> is a similar pretend type. It symbolises 'any monad'. </p> <h3 id="9581579bd43f47cf9973222d0bbec20c"> Kleisli composition <a href="#9581579bd43f47cf9973222d0bbec20c" title="permalink">#</a> </h3> <p> In <a href="/2021/11/22/functions-as-pipes">Functions as pipes</a> you got a visual illustration of how functions compose. If you have a function that returns a Boolean value, you can use that Boolean value as input to a function that accepts Boolean values as input. Generalised, if one function returns <code>a</code> and another function accepts <code>a</code> as input, you can compose these two functions: </p> <p> <pre>(a -&gt; b) -&gt; (b -&gt; c) -&gt; (a -&gt; c)</pre> </p> <p> A combinator of this type takes two functions as input: <code>a -&gt; b</code> (a function from <code>a</code> to <code>b</code>) and <code>(b -&gt; c)</code>, and returns a new function that 'hides' the middle step: <code>a -&gt; c</code>. </p> <p> If this is possible, it seems intuitive that you can also compose monadic functions: </p> <p> <pre>(&gt;=&gt;) :: Monad m =&gt; (a -&gt; m b) -&gt; (b -&gt; m c) -&gt; a -&gt; m c</pre> </p> <p> The <a href="https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:-62--61--62-">&gt;=&gt;</a> operator is known as the <em>fish</em> operator - or more precisely the <em>right fish</em> operator, since there's also a <em>left fish</em> operator <a href="https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:-60--61--60-">&lt;=&lt;</a>. </p> <p> This is known as <em>Kleisli composition</em>. In C# you could write it like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;T,&nbsp;Monad&lt;T2&gt;&gt;&nbsp;<span style="color:#74531f;">Compose</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Func&lt;T,&nbsp;Monad&lt;T1&gt;&gt;&nbsp;<span style="color:#1f377f;">action1</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;Monad&lt;T2&gt;&gt;&nbsp;<span style="color:#1f377f;">action2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;action1(x).SelectMany(action2); }</pre> </p> <p> Notice that Kleisli composition works for any monad. You don't need any new abilities in order to compose a monad in this way. The composition exclusively relies on <code>SelectMany</code> (monadic <em>bind</em>). </p> <p> Here's a usage example: </p> <p> <pre>Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Monad.Return(s.Length); Func&lt;<span style="color:blue;">int</span>,&nbsp;Monad&lt;<span style="color:blue;">bool</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;Monad.Return(i&nbsp;%&nbsp;2&nbsp;==&nbsp;0); Func&lt;<span style="color:blue;">string</span>,&nbsp;Monad&lt;<span style="color:blue;">bool</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">composed</span>&nbsp;=&nbsp;f.Compose(g);</pre> </p> <p> The <code>Compose</code> method corresponds to the right fish operator, but obviously you could define an overload that flips the arguments. That would correspond to the left fish operator. </p> <h3 id="6c831b646c374287a07c3918097818e2"> Universality <a href="#6c831b646c374287a07c3918097818e2" title="permalink">#</a> </h3> <p> Kleisli composition seems compelling, but in reality I find that I rarely use it. If it isn't that useful, then why dedicate an entire article to it? </p> <p> As I wrote in the introduction, it's mostly because it gives us an intuitive way to describe the monad laws. </p> <p> Kleisli arrows form a <a href="https://en.wikipedia.org/wiki/Category_theory">category</a>. As such, it's a universal abstraction. I admit that <a href="/2017/10/04/from-design-patterns-to-category-theory">this article series</a> has strayed away from its initial vision of discussing category theory, but I still find it assuring when I encounter some bedrock of theory behind a programming concept. </p> <h3 id="afc020e8bbe7436b891782b8d469c111"> Conclusion <a href="#afc020e8bbe7436b891782b8d469c111" title="permalink">#</a> </h3> <p> Kleisli composition lets you compose two (or more) compatible monadic functions into a single monadic function. </p> <p> <strong>Next:</strong> <a href="/2022/04/11/monad-laws">Monad laws</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Monads https://blog.ploeh.dk/2022/03/28/monads 2022-03-28T06:12:00+00:00 Mark Seemann <div id="post"> <p> <em>A monad is a common abstraction. While typically associated with Haskell, monads also exist in C# and other languages.</em> </p> <p> This article series is part of <a href="/2018/03/19/functors-applicatives-and-friends">a larger series of articles about functors, applicatives, and other mappable containers</a>. </p> <p> If you understand what a <a href="/2018/03/22/functors">functor</a> is, it should be easy to grasp the idea of a monad. <em>It's a functor you can flatten.</em> </p> <p> There's a little more to it than that, and you also need to learn what I mean by <em>flatten</em>, but that's the essence of it. </p> <p> In this article-series-within-an-article series, I'll explain this disproportionally dreaded concept, giving you plenty of examples as well as a more formal definition. Examples will be in both C#, <a href="https://fsharp.org">F#</a>, and <a href="https://www.haskell.org">Haskell</a>, although I plan to emphasise C#. I expect that there's little need of explaining monads to people already familiar with Haskell. I'll show examples as separate articles in this series. These articles are mostly aimed at object-oriented programmers curious about monads. </p> <ul> <li><a href="/2022/04/04/kleisli-composition">Kleisli composition</a></li> <li><a href="/2022/04/11/monad-laws">Monad laws</a></li> <li><a href="/2022/04/19/the-list-monad">The List monad</a></li> <li><a href="/2022/04/25/the-maybe-monad">The Maybe monad</a></li> <li><a href="/2022/05/09/an-either-monad">An Either monad</a></li> <li><a href="/2022/05/16/the-identity-monad">The Identity monad</a></li> <li>The Lazy monad</li> <li>Asynchronous monads</li> <li>The State monad</li> <li>The Reader monad</li> <li>The IO monad</li> </ul> <p> This list is far from exhaustive; more monads exist. </p> <p> <img src="/content/binary/functors-applicatives-monads.png" alt="Set diagram with monads shown as a subset of applicatives, which is shown as a subset of functors, again a subset of generic types."> </p> <p> All monads are <a href="/2018/10/01/applicative-functors">applicative functors</a>, but not all applicative functors are monads. As the set diagram reiterates, applicative functors are functors, but again: not necessarily the other way around. </p> <h3 id="a342785804ef4d5ebb6e88cef8140432"> Flattening <a href="#a342785804ef4d5ebb6e88cef8140432" title="permalink">#</a> </h3> <p> A monad is a functor you can flatten. What do I mean by <em>flatten?</em> </p> <p> As in <a href="/2018/03/22/functors">the article that introduces functors</a>, imagine that you have some <code>Functor&lt;T&gt;</code> <a href="https://bartoszmilewski.com/2014/01/14/functors-are-containers">container</a>. More concretely, this could be <code>IEnumerable&lt;T&gt;</code>, <code>Maybe&lt;T&gt;</code>, <code>Task&lt;T&gt;</code>, etcetera. </p> <p> When working with functors, you sometimes run into situations where the containers nest inside each other. Instead of a <code>Functor&lt;decimal&gt;</code>, you may find yourself with a <code>Functor&lt;Functor&lt;decimal&gt;&gt;</code>, or maybe even an object that's thrice or quadruply nested. </p> <p> If you can flatten such nested functor objects to just <code>Functor&lt;T&gt;</code>, then that functor also forms a monad. </p> <p> In C#, you need a method with this kind of signature: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Functor&lt;T&gt;&nbsp;<span style="color:#74531f;">Flatten</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;Functor&lt;Functor&lt;T&gt;&gt;&nbsp;<span style="color:#1f377f;">source</span>)</pre> </p> <p> Notice that this method takes a <code>Functor&lt;Functor&lt;T&gt;&gt;</code> as input and returns a <code>Functor&lt;T&gt;</code> as output. I'm not showing the actual implementation, since <code>Functor&lt;T&gt;</code> is really just a 'pretend' functor (and monad). In the example articles that follow, you'll see actual implementation code. </p> <p> With <code>Flatten</code> you can write code like this: </p> <p> <pre>Functor&lt;<span style="color:blue;">decimal</span>&gt;&nbsp;<span style="color:#1f377f;">dest</span>&nbsp;=&nbsp;source.Flatten();</pre> </p> <p> Here, <code>source</code> is a <code>Functor&lt;Functor&lt;<span style="color:blue;">decimal</span>&gt;&gt;</code>. </p> <p> This function also exists in Haskell, although there, it's called <a href="https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:join">join</a>: </p> <p> <pre>join :: Monad m =&gt; m (m a) -&gt; m a</pre> </p> <p> For any <code>Monad m</code> you can flatten or join a nested monad <code>m (m a)</code> to a 'normal' monad <code>m a</code>. </p> <p> This is the same function as <code>Flatten</code>, so in C# we could define an alias like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Functor&lt;T&gt;&nbsp;<span style="color:#74531f;">Join</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;Functor&lt;Functor&lt;T&gt;&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.Flatten(); }</pre> </p> <p> Usually, however, you don't see monads introduced via <code>join</code> or <code>Flatten</code>. It's a shame, really, because it's the most straightforward description. </p> <h3 id="948d267819284e61af68d575c9d294e6"> Bind <a href="#948d267819284e61af68d575c9d294e6" title="permalink">#</a> </h3> <p> Most languages that come with a notion of monads define them via a function colloquially referred to as <em>monadic bind</em> or just <em>bind</em>. In C# it's called <code>SelectMany</code>, <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/computation-expressions">F# computation expressions</a> call it <code>Bind</code>, and Scala calls it <code>flatMap</code> (with a vestige of the concept of flattening). Haskell just defines it as an operator: </p> <p> <pre>(&gt;&gt;=) :: Monad m =&gt; m a -&gt; (a -&gt; m b) -&gt; m b</pre> </p> <p> When talking about it, I tend to call the <code>&gt;&gt;=</code> operator <em>bind</em>. </p> <p> Translated to C# it has this kind of signature: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Functor&lt;TResult&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Functor&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Functor&lt;TResult&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>)</pre> </p> <p> It looks almost like a functor's <code>Select</code> method (AKA <code>map</code> or <code>fmap</code> function). The difference is that this <code>selector</code> returns a functor value (<code>Functor&lt;TResult&gt;</code>) rather than a 'naked' <code>TResult</code> value. </p> <p> When a <code>Flatten</code> (or <code>Join</code>) method already exists, you can always implement <code>SelectMany</code> like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Functor&lt;TResult&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Functor&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Functor&lt;TResult&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Functor&lt;Functor&lt;TResult&gt;&gt;&nbsp;<span style="color:#1f377f;">nest</span>&nbsp;=&nbsp;source.Select(selector); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;nest.Flatten(); }</pre> </p> <p> I've split the implementation over two lines of code to make it clearer what's going on. That's also the reason I've used an explicit type declaration rather than <code>var</code>. </p> <p> The <code>Select</code> method exists because the type is already a functor. When you call <code>Select</code> with <code>selector</code> you get a <code>Functor&lt;Functor&lt;TResult&gt;&gt;</code> because <code>selector</code> itself returns a <code>Functor&lt;TResult&gt;</code>. That's a nested functor, which you can <code>Flatten</code>. </p> <p> You can use <code>SelectMany</code> like this: </p> <p> <pre>Functor&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">source</span>&nbsp;=&nbsp;Functor.Return(TimeSpan.FromMinutes(32)); Functor&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">dest</span>&nbsp;=&nbsp;source.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;Functor.Return(x.TotalSeconds&nbsp;+&nbsp;192));</pre> </p> <p> The lambda expression returns a <code>Functor&lt;double&gt;</code>. Had you called <code>Select</code> with this lambda expression, the result would have been a nested functor. <code>SelectMany</code>, however, flattens while it maps (it <em>flatMaps</em>). (This example is rather inane, since it would be simpler to use <code>Select</code> and omit wrapping the output of the lambda in the functor. The later articles in this series will show some more compelling examples.) </p> <p> If you already have <code>Flatten</code> (or <code>Join</code>) you can always implement <code>SelectMany</code> like this. Usually, however, languages use monadic bind (e.g. <code>SelectMany</code>) as the foundation. Both C#, Haskell, and F# do that. In that case, it's also possible to go the other way and implement <code>Flatten</code> with <code>SelectMany</code>. You'll see examples of that in the subsequent articles. </p> <h3 id="ed8ec161f2f3424089c5c0cee07d5fbd"> Syntactic sugar <a href="#ed8ec161f2f3424089c5c0cee07d5fbd" title="permalink">#</a> </h3> <p> Several languages understand monads well enough to provide some degree of syntactic sugar. While you can always use <code>SelectMany</code> in C# by simply calling the method, there are situations where that becomes awkward. The same is true with <code>bind</code> functions in F# and <code>&gt;&gt;=</code> in Haskell. </p> <p> In C# you can use <em>query syntax</em>: </p> <p> <pre>Functor&lt;DateTime&gt;&nbsp;<span style="color:#1f377f;">fdt</span>&nbsp;=&nbsp;Functor.Return(<span style="color:blue;">new</span>&nbsp;DateTime(2001,&nbsp;8,&nbsp;3)); Functor&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">fts</span>&nbsp;=&nbsp;Functor.Return(TimeSpan.FromDays(4)); Functor&lt;DateTime&gt;&nbsp;<span style="color:#1f377f;">dest</span>&nbsp;=&nbsp;<span style="color:blue;">from</span>&nbsp;dt&nbsp;<span style="color:blue;">in</span>&nbsp;fdt &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;ts&nbsp;<span style="color:blue;">in</span>&nbsp;fts &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;dt&nbsp;-&nbsp;ts;</pre> </p> <p> In order to support more than a single <code>from</code> expression, however, you must supply a special <code>SelectMany</code> overload, or the code doesn't compile: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Functor&lt;TResult&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">U</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Functor&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Functor&lt;U&gt;&gt;&nbsp;<span style="color:#1f377f;">k</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;U,&nbsp;TResult&gt;&nbsp;<span style="color:#1f377f;">s</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;k(x).Select(<span style="color:#1f377f;">y</span>&nbsp;=&gt;&nbsp;s(x,&nbsp;y))); }</pre> </p> <p> This is an odd quirk of C# that I've yet to encounter in other languages, and I consider it <a href="/2019/12/16/zone-of-ceremony">ceremony</a> that I have to perform to satiate the C# compiler. It's not part of the concept of what a monad is. As far as I can tell, you can always implement it like shown here. </p> <p> Haskell's syntactic sugar is called <em>do notation</em> and works for all monads: </p> <p> <pre><span style="color:#2b91af;">example</span>&nbsp;::&nbsp;(<span style="color:blue;">Monad</span>&nbsp;m,&nbsp;<span style="color:blue;">Num</span>&nbsp;a)&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;m&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;m&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;m&nbsp;a example&nbsp;fdt&nbsp;fts&nbsp;=&nbsp;<span style="color:blue;">do</span> &nbsp;&nbsp;dt&nbsp;&lt;-&nbsp;fdt &nbsp;&nbsp;ts&nbsp;&lt;-&nbsp;fts &nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;$&nbsp;dt&nbsp;-&nbsp;ts</pre> </p> <p> In F#, <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/computation-expressions">computation expressions</a> drive syntactic sugar, but still based (among other things) on the concept of a monad: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;example&nbsp;(fdt&nbsp;:&nbsp;Monad&lt;DateTime&gt;)&nbsp;(fts&nbsp;:&nbsp;Monad&lt;TimeSpan&gt;)&nbsp;=&nbsp;monad&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;dt&nbsp;=&nbsp;fdt &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;ts&nbsp;=&nbsp;fts &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;dt&nbsp;-&nbsp;ts&nbsp;}</pre> </p> <p> Here, we again have to pretend that a <code>Monad&lt;'a&gt;</code> type exists, with a companion <code>monad</code> computation expression. </p> <h3 id="440abd098e1144c78229eb0ee2d0ad4f"> Return <a href="#440abd098e1144c78229eb0ee2d0ad4f" title="permalink">#</a> </h3> <p> The ability to flatten nested functors is the essence of what a monad is. There are, however, also some formal requirements. As is the case with functors, there are laws that a monad should obey. I'll dedicate <a href="/2022/04/11/monad-laws">a separate article</a> for those, so we'll skip them for now. </p> <p> Another requirement is that in addition to <code>SelectMany</code>/<code>bind</code>/<code>flatMap</code>/<code>&gt;&gt;=</code> a monad must also provide a method to 'elevate' a value to the monad. This function is usually called <em>return</em>. It should have a type like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Functor&lt;T&gt;&nbsp;<span style="color:#74531f;">Return</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)</pre> </p> <p> You can see it in use in the above code snippet, and with the relevant parts repeated here: </p> <p> <pre>Functor&lt;DateTime&gt;&nbsp;<span style="color:#1f377f;">fdt</span>&nbsp;=&nbsp;Functor.Return(<span style="color:blue;">new</span>&nbsp;DateTime(2001,&nbsp;8,&nbsp;3)); Functor&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">fts</span>&nbsp;=&nbsp;Functor.Return(TimeSpan.FromDays(4));</pre> </p> <p> This code example lifts the value <code>DateTime(2001,&nbsp;8,&nbsp;3)</code> to a <code>Functor&lt;DateTime&gt;</code> value, and the value <code>TimeSpan.FromDays(4)</code> to a <code>Functor&lt;TimeSpan&gt;</code> value. </p> <p> Usually, in a language like C# a concrete monad type may either afford a constructor or factory method for this purpose. You'll see examples in the articles that give specific monad examples. </p> <h3 id="558c849b4c644f9fb28c788aa43cb263"> Conclusion <a href="#558c849b4c644f9fb28c788aa43cb263" title="permalink">#</a> </h3> <p> A monad is a functor you can flatten. That's the simplest way I can put it. </p> <p> In this article you learned what <em>flattening</em> means. You also learned that a monad must obey some laws and have a <em>return</em> function. The essence, however, is flattening. The laws just ensure that the flattening is well-behaved. </p> <p> It may not yet be clear to you why some functors would need flattening in the first place, but subsequent articles will show examples. </p> <p> The word <em>monad</em> has its own mystique in software development culture. If you've ever encountered some <a href="/2021/06/07/abstruse-nomenclature">abstruse nomenclature</a> about monads, then try to forget about it. The concept is really not hard to grasp, and it usually clicks once you've seen enough examples, and perhaps done some exercises. </p> <p> <strong>Next:</strong> <a href="/2022/04/04/kleisli-composition">Kleisli composition</a>. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="86bf8188e50f4dee891bde7f2b7a8225"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <p>Quoting image in words:</p> <blockquote> <ul> <li>Every Monad is an applicative functor</li> <li>Every applicative functor is a functor</li> <li>Every functor is a generic type</li> </ul> </blockquote> <p> As your aricle about <a href="https://blog.ploeh.dk/2020/10/19/monomorphic-functors/">Monomorphic functors</a> shows, not every functor is a generic type. However, it is true that every applicative functor is a generic (or polymorphic) functor. </p> </div> <div class="comment-date">2022-04-18 15:28 UTC</div> </div> <div class="comment" id="2971857cfe8d4766bb48b37ce92eef4b"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> True, the illustration is a simplification. </p> </div> <div class="comment-date">2022-04-18 20:38 UTC</div> </div> <div class="comment" id="adddc3fdc50ac979899dfbe272794544"> <div class="comment-author"><a href="https://github.com/mormegil-cz">Petr Kadlec</a></div> <div class="comment-content"> <p> I guess you might know that already but the reason for the strange <code>SelectMany</code> ceremonial version is compiler performance. The complicated form is needed so that the overload resolution does not take exponential amount of time. See <a href="https://ericlippert.com/2013/04/02/monads-part-twelve/">a 2013 article by Eric Lippert covering this</a>. </p> </div> <div class="comment-date">2022-05-02 11:50 UTC</div> </div> <div class="comment" id="f7409894f143485683c9862221f3a903"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Petr, thank you for writing. I remember reading about it before, but it's good to have a proper source. </p> <p> If I understand the article correctly, the problem seems to originate from overload resolution. This would, at least, explain why neither F# nor Haskell needs that extra overload. I wonder if a language like Java would have a similar problem, but I don't think that Java has syntactic sugar for monads. </p> <p> It still seems a little strange that the C# compiler <em>requires</em> the presence of that overload. Eric Lippert seems to strongly imply that it's always possible to derive that extra overload from any monad's fundamental functions (as is also my conjecture). If this is so, the C# compiler should be able to do that work by itself. Monads that wish to supply a more efficient implement (e.g. <code>IEnumerable&lt;T&gt;</code>) could still do so: The C# compiler could look for the overload and use it if it finds it, and still fall back to the default implementation if none is available. </p> <p> But I suppose that since the query syntax feature only really exists to support <code>IEnumerable&lt;T&gt;</code> this degree of sophistication wasn't warranted. </p> </div> <div class="comment-date">2022-05-03 6:12 UTC</div> </div> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Contravariant Dependency Injection https://blog.ploeh.dk/2022/03/21/contravariant-dependency-injection 2022-03-21T06:46:00+00:00 Mark Seemann <div id="post"> <p> <em>How to use a DI Container in FP... or not.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction, and a few of the examples. </p> <p> People sometimes ask me how to do Dependency Injection (DI) in Functional Programming (FP). The short answer is that <a href="/2017/01/27/from-dependency-injection-to-dependency-rejection">you don't, because dependencies make functions impure</a>. If you're having the discussion on Twitter, you may get some drive-by comments to the effect that <em>DI is just a contravariant functor</em>. (I've seen such interactions take place, but currently can't find the specific examples.) </p> <p> What might people mean by that? </p> <p> In this article, I'll explain. You'll also see how this doesn't address the underlying problem that DI makes everything impure. Ultimately, then, it doesn't really matter. It's still not functional. </p> <h3 id="43f01ded1bbd42e28a90f398152518ff"> Partial application as Dependency Injection <a href="#43f01ded1bbd42e28a90f398152518ff" title="permalink">#</a> </h3> <p> As example code, let's revisit the code from the article <a href="/2017/01/30/partial-application-is-dependency-injection">Partial application is dependency injection</a>. You may have an impure action like this: </p> <p> <pre><span style="color:green;">//&nbsp;int&nbsp;-&gt;&nbsp;(DateTimeOffset&nbsp;-&gt;&nbsp;Reservation&nbsp;list)&nbsp;-&gt;&nbsp;(Reservation&nbsp;-&gt;&nbsp;int)&nbsp;-&gt;&nbsp;Reservation</span> <span style="color:green;">//&nbsp;-&gt;&nbsp;int&nbsp;option</span> <span style="color:blue;">let</span>&nbsp;tryAccept&nbsp;capacity&nbsp;readReservations&nbsp;createReservation&nbsp;reservation&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;reservedSeats&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readReservations&nbsp;reservation.Date&nbsp;|&gt;&nbsp;List.sumBy&nbsp;(<span style="color:blue;">fun</span>&nbsp;x&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;x.Quantity) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;reservedSeats&nbsp;+&nbsp;reservation.Quantity&nbsp;&lt;=&nbsp;capacity &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">then</span>&nbsp;createReservation&nbsp;{&nbsp;reservation&nbsp;<span style="color:blue;">with</span>&nbsp;IsAccepted&nbsp;=&nbsp;<span style="color:blue;">true</span>&nbsp;}&nbsp;|&gt;&nbsp;Some &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">else</span>&nbsp;None</pre> </p> <p> The <code>readReservations</code> and <code>createReservation</code> 'functions' will in reality be impure actions that read from and write to a database. Since they are impure, the entire <code>tryAccept</code> action is impure. That's the result from that article. </p> <p> In this example the 'dependencies' are pushed to the left. This enables you to partially apply the 'function' with the dependencies: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;sut&nbsp;=&nbsp;tryAccept&nbsp;capacity&nbsp;readReservations&nbsp;createReservation</pre> </p> <p> This code example is from a unit test, which is the reason that I've <a href="https://docs.microsoft.com/en-us/archive/blogs/ploeh/naming-sut-test-variables">named the partially applied 'function' <code>sut</code></a>. It has the type <code>Reservation -&gt; int option</code>. Keep in mind that while it looks like a regular function, in practice it'll be an impure action. </p> <p> You can invoke <code>sut</code> like another other function: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;sut&nbsp;reservation</pre> </p> <p> When you do this, <code>tryAccept</code> will execute, interact with the partially applied dependencies, and return a result. </p> <p> Partial application is a standard practice in FP, and in itself it's useful. Using it for Dependency Injection, however, doesn't magically make DI functional. DI remains impure, which also means that the entire <code>sut</code> composition is impure. </p> <h3 id="88c2633d1dd34a979aaca1a223ff665b"> Moving dependencies to the right <a href="#88c2633d1dd34a979aaca1a223ff665b" title="permalink">#</a> </h3> <p> Pushing dependencies to the left enables partial application. Dependencies are typically more long-lived than run-time values like <code>reservation</code>. Thus, partially applying the dependencies as shown above makes sense. If all dependencies are thread-safe, you can let an action like <code>sut</code>, above, have Singleton lifetime. In other words, just keep a single, stateless <code>Reservation -&gt; int option</code> action around for the lifetime of the application, and pass it <code>Reservation</code> values as they arrive. </p> <p> Moving dependencies to the right seems, then, counterproductive. </p> <p> <pre><span style="color:green;">//&nbsp;Reservation&nbsp;-&gt;&nbsp;int&nbsp;-&gt;&nbsp;(DateTimeOffset&nbsp;-&gt;&nbsp;Reservation&nbsp;list)&nbsp;-&gt;&nbsp;(Reservation&nbsp;-&gt;&nbsp;int)</span> <span style="color:green;">//&nbsp;-&gt;&nbsp;int&nbsp;option</span> <span style="color:blue;">let</span>&nbsp;tryAccept&nbsp;reservation&nbsp;capacity&nbsp;readReservations&nbsp;createReservation&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;reservedSeats&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readReservations&nbsp;reservation.Date&nbsp;|&gt;&nbsp;List.sumBy&nbsp;(<span style="color:blue;">fun</span>&nbsp;x&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;x.Quantity) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;reservedSeats&nbsp;+&nbsp;reservation.Quantity&nbsp;&lt;=&nbsp;capacity &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">then</span>&nbsp;createReservation&nbsp;{&nbsp;reservation&nbsp;<span style="color:blue;">with</span>&nbsp;IsAccepted&nbsp;=&nbsp;<span style="color:blue;">true</span>&nbsp;}&nbsp;|&gt;&nbsp;Some &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">else</span>&nbsp;None</pre> </p> <p> If you move the dependencies to the right, you can no longer partially apply them, so what would be the point of that? </p> <p> As given above, it seems that you'll have to supply all arguments in one go: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;tryAccept&nbsp;reservation&nbsp;capacity&nbsp;readReservations&nbsp;createReservation</pre> </p> <p> If, on the other hand, you turn all the dependencies into a tuple, some new options arise: </p> <p> <pre><span style="color:green;">//&nbsp;Reservation&nbsp;-&gt;&nbsp;(int&nbsp;*&nbsp;(DateTimeOffset&nbsp;-&gt;&nbsp;Reservation&nbsp;list)&nbsp;*&nbsp;(Reservation&nbsp;-&gt;&nbsp;int))</span> <span style="color:green;">//&nbsp;-&gt;&nbsp;int&nbsp;option</span> <span style="color:blue;">let</span>&nbsp;tryAccept&nbsp;reservation&nbsp;(capacity,&nbsp;readReservations,&nbsp;createReservation)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;reservedSeats&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readReservations&nbsp;reservation.Date&nbsp;|&gt;&nbsp;List.sumBy&nbsp;(<span style="color:blue;">fun</span>&nbsp;x&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;x.Quantity) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;reservedSeats&nbsp;+&nbsp;reservation.Quantity&nbsp;&lt;=&nbsp;capacity &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">then</span>&nbsp;createReservation&nbsp;{&nbsp;reservation&nbsp;<span style="color:blue;">with</span>&nbsp;IsAccepted&nbsp;=&nbsp;<span style="color:blue;">true</span>&nbsp;}&nbsp;|&gt;&nbsp;Some &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">else</span>&nbsp;None</pre> </p> <p> I decided to count <code>capacity</code> as a dependency, since this is most likely a value that originates from a configuration setting somewhere. Thus, it'd tend to have a singleton lifetime equivalent to <code>readReservations</code> and <code>createReservation</code>. </p> <p> It still seems that you have to supply all the arguments, though: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;tryAccept&nbsp;reservation&nbsp;(capacity,&nbsp;readReservations,&nbsp;createReservation)</pre> </p> <p> What's the point, then? </p> <h3 id="8bf311e8b5184d1396e7f49b5b9d9b48"> Reader <a href="#8bf311e8b5184d1396e7f49b5b9d9b48" title="permalink">#</a> </h3> <p> You can view all functions as values of the <a href="/2021/11/08/reader-as-a-profunctor">Reader profunctor</a>. This, then, is also true for <code>tryAccept</code>. It's an (impure) function that takes a <code>Reservation</code> as input, and returns a Reader value as output. The 'Reader environment' is a tuple of dependencies, and the output is <code>int option</code>. </p> <p> First, add an explicit <code>Reader</code> module: </p> <p> <pre><span style="color:green;">//&nbsp;&#39;a&nbsp;-&gt;&nbsp;(&#39;a&nbsp;-&gt;&nbsp;&#39;b)&nbsp;-&gt;&nbsp;&#39;b</span> <span style="color:blue;">let</span>&nbsp;run&nbsp;env&nbsp;rdr&nbsp;=&nbsp;rdr&nbsp;env <span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;&#39;b)&nbsp;-&gt;&nbsp;(&#39;c&nbsp;-&gt;&nbsp;&#39;d)&nbsp;-&gt;&nbsp;(&#39;b&nbsp;-&gt;&nbsp;&#39;c)&nbsp;-&gt;&nbsp;&#39;a&nbsp;-&gt;&nbsp;&#39;d</span> <span style="color:blue;">let</span>&nbsp;dimap&nbsp;f&nbsp;g&nbsp;rdr&nbsp;=&nbsp;<span style="color:blue;">fun</span>&nbsp;env&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;g&nbsp;(rdr&nbsp;(f&nbsp;env)) <span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;&#39;b)&nbsp;-&gt;&nbsp;(&#39;c&nbsp;-&gt;&nbsp;&#39;a)&nbsp;-&gt;&nbsp;&#39;c&nbsp;-&gt;&nbsp;&#39;b</span> <span style="color:blue;">let</span>&nbsp;map&nbsp;g&nbsp;=&nbsp;dimap&nbsp;id&nbsp;g <span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;&#39;b)&nbsp;-&gt;&nbsp;(&#39;b&nbsp;-&gt;&nbsp;&#39;c)&nbsp;-&gt;&nbsp;&#39;a&nbsp;-&gt;&nbsp;&#39;c</span> <span style="color:blue;">let</span>&nbsp;contraMap&nbsp;f&nbsp;=&nbsp;dimap&nbsp;f&nbsp;id</pre> </p> <p> The <code>run</code> function is mostly there to make the Reader concept more explicit. The <code>dimap</code> implementation is what makes Reader a <a href="/2021/11/01/profunctors">profunctor</a>. You can use <code>dimap</code> to implement <code>map</code> and <code>contraMap</code>. In the following, we're not going to need <code>map</code>, but I still included it for good measure. </p> <p> You can partially apply the last version of <code>tryAccept</code> with a <code>reservation</code>: </p> <p> <pre><span style="color:green;">//&nbsp;sut&nbsp;:&nbsp;(int&nbsp;*&nbsp;(DateTimeOffset&nbsp;-&gt;&nbsp;Reservation&nbsp;list)&nbsp;*&nbsp;(Reservation&nbsp;-&gt;&nbsp;int))&nbsp;-&gt;&nbsp;int&nbsp;option</span> <span style="color:blue;">let</span>&nbsp;sut&nbsp;=&nbsp;tryAccept&nbsp;reservation</pre> </p> <p> You can view the <code>sut</code> value as a Reader. The 'environment' is the tuple of dependencies, and the output is still <code>int option</code>. Since we can <a href="/2022/03/07/a-type-safe-di-container-as-a-tuple">view a tuple as a type-safe DI Container</a>, we've now introduced a DI Container to the 'function'. We can say that the action is a Reader of the DI Container. </p> <p> You can <code>run</code> the action by supplying a <code>container</code>: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;container&nbsp;=&nbsp;(capacity,&nbsp;readReservations,&nbsp;createReservation) <span style="color:blue;">let</span>&nbsp;sut&nbsp;=&nbsp;tryAccept&nbsp;reservation <span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;sut&nbsp;|&gt;&nbsp;Reader.run&nbsp;container</pre> </p> <p> This <code>container</code>, however, is specialised to fit <code>tryAccept</code>. What if other actions require other dependencies? </p> <h3 id="ada91148e72f45e3b274d89e19644f50"> Contravariant mapping <a href="#ada91148e72f45e3b274d89e19644f50" title="permalink">#</a> </h3> <p> In a larger system, you're likely to have more than the three dependencies shown above. Other actions require other dependencies, and may not need <code>capacity</code>, <code>readReservations</code>, or <code>createReservation</code>. </p> <p> To make the point, perhaps the <code>container</code> looks like this: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;container&nbsp;=&nbsp;(capacity,&nbsp;readReservations,&nbsp;createReservation,&nbsp;someOtherService,&nbsp;yetAnotherService)</pre> </p> <p> If you try to <code>run</code> a partially applied Reader like <code>sut</code> with this action, your code doesn't compile. <code>sut</code> needs a triple of a specific type, but <code>container</code> is now a pentuple. Should you change <code>tryAccept</code> so that it takes the bigger pentuple as a parameter? </p> <p> That would compile, but would be a leaky abstraction. It would also violate the <a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion Principle</a> and the <a href="https://en.wikipedia.org/wiki/Interface_segregation_principle">Interface Segregation Principle</a> because <code>tryAccept</code> would require callers to supply a bigger argument than is needed. </p> <p> Instead, you can <code>contraMap</code> the pentuple: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;container&nbsp;=&nbsp;(capacity,&nbsp;readReservations,&nbsp;createReservation,&nbsp;someOtherService,&nbsp;yetAnotherService) <span style="color:blue;">let</span>&nbsp;sut&nbsp;=&nbsp;tryAccept&nbsp;reservation&nbsp;|&gt;&nbsp;Reader.contraMap&nbsp;(<span style="color:blue;">fun</span>&nbsp;(c,&nbsp;rr,&nbsp;cr,&nbsp;_,&nbsp;_)&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;(c,&nbsp;rr,&nbsp;cr)) <span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;sut&nbsp;|&gt;&nbsp;Reader.run&nbsp;container</pre> </p> <p> This turns <code>sut</code> into a Reader of the pentuple, instead of a Reader of the triple. You can now <code>run</code> it with the pentuple <code>container</code>. <code>tryAccept</code> remains a Reader of the triple. </p> <h3 id="e8cb20a7be2342f7802f6522fa5edd5a"> Conclusion <a href="#e8cb20a7be2342f7802f6522fa5edd5a" title="permalink">#</a> </h3> <p> Keep in mind that <code>tryAccept</code> remains impure. While this may look impressively functional, it really isn't. It doesn't address the original problem that <a href="/2021/07/28/referential-transparency-fits-in-your-head">composition of impure actions creates larger impure actions that don't fit in your head</a>. </p> <p> Why, then, make things more complicated than they have to be? </p> <p> In FP, I'd look long and hard for a better alternative - one that obeys <a href="/2018/11/19/functional-architecture-a-definition">the functional architecture law</a>. If, for various reasons, I was unable to produce a purely functional design, I'd prefer composing impure actions with partial application. It's simpler. </p> <p> This article isn't an endorsement of using contravariant DI in FP. It's only meant as an explanation of a phrase like <em>DI is just a contravariant functor</em>. </p> <p> <strong>Next:</strong> <a href="/2021/11/01/profunctors">Profunctors</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Type-safe DI Containers are redundant https://blog.ploeh.dk/2022/03/14/type-safe-di-containers-are-redundant 2022-03-14T05:27:00+00:00 Mark Seemann <div id="post"> <p> <em>Just use Pure DI.</em> </p> <p> This article is part of a series called <a href="/2022/01/10/type-safe-di-composition">Type-safe DI composition</a>. In the previous article, you saw <a href="/2022/03/07/a-type-safe-di-container-as-a-tuple">how tuples are adequate DI Containers</a>. In case it's not clear from the article that introduces the series, there's really no point to any of this. My motivation for writing the article is that readers sometimes ask me about topics such as DI Containers versus type safety, or DI Containers in functional programming. The goal of these articles is to make it painfully clear why I find such ideas moot. </p> <h3 id="5cc2827dd110479c980af791313d03da"> Tuples as DI Containers <a href="#5cc2827dd110479c980af791313d03da" title="permalink">#</a> </h3> <p> In the <a href="/2022/03/07/a-type-safe-di-container-as-a-tuple">previous article</a> you saw how tuples make adequate DI Containers. Consider, however, this constructor: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&nbsp;container; <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">CompositionRoot</span>( &nbsp;&nbsp;&nbsp;&nbsp;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&nbsp;<span style="color:#1f377f;">container</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.container&nbsp;=&nbsp;container; }</pre> </p> <p> One question, though: Why pass a tuple of three objects as a single argument? Wouldn't it be more <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a> to use a normal argument list? </p> <h3 id="1612596b46e045bbae911e2868a4bbfe"> Argument list <a href="#1612596b46e045bbae911e2868a4bbfe" title="permalink">#</a> </h3> <p> Just remove the brackets around the tuple argument and dissolve the elements into separate class fields: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IRestaurantDatabase&nbsp;rdb; <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IClock&nbsp;clock; <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IReservationsRepository&nbsp;repo; <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">CompositionRoot</span>(IRestaurantDatabase&nbsp;<span style="color:#1f377f;">rdb</span>,&nbsp;IClock&nbsp;<span style="color:#1f377f;">clock</span>,&nbsp;IReservationsRepository&nbsp;<span style="color:#1f377f;">repo</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.rdb&nbsp;=&nbsp;rdb; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.clock&nbsp;=&nbsp;clock; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repo&nbsp;=&nbsp;repo; }</pre> </p> <p> You no longer need to <a href="/2010/09/29/TheRegisterResolveReleasepattern">resolve</a> services from a DI Container. You can simply use the class fields directly: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">object</span>&nbsp;<span style="color:#74531f;">Create</span>(ControllerContext&nbsp;<span style="color:#1f377f;">context</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(context&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(context)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;context.ActionDescriptor.ControllerTypeInfo; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(CalendarController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;CalendarController(rdb,&nbsp;repo); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(HomeController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;HomeController(rdb); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ReservationsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationsController(clock,&nbsp;rdb,&nbsp;repo); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(RestaurantsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;RestaurantsController(rdb); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ScheduleController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ScheduleController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rdb, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repo, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AccessControlList.FromUser(context.HttpContext.User)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;Unexpected&nbsp;controller&nbsp;type:&nbsp;</span>{t}<span style="color:#a31515;">.&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(context)); }</pre> </p> <p> Instead of <code>container.rdb</code>, <code>container.repo</code>, and <code>container.clock</code>, you can simply access <code>rdb</code>, <code>repo</code>, and <code>clock</code>. </p> <p> The <a href="/2010/09/29/TheRegisterResolveReleasepattern">registration phase</a> (such as it now remains) also becomes simpler: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">rdb</span>&nbsp;=&nbsp;CompositionRoot.CreateRestaurantDatabase(Configuration); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">po</span>&nbsp;=&nbsp;CompositionRoot.CreatePostOffice(Configuration,&nbsp;rdb); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">clock</span>&nbsp;=&nbsp;CompositionRoot.CreateClock(); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">repo</span>&nbsp;=&nbsp;CompositionRoot.CreateRepository(Configuration,&nbsp;po); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">compositionRoot</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompositionRoot(rdb,&nbsp;clock,&nbsp;repo); services.AddSingleton&lt;IControllerActivator&gt;(compositionRoot);</pre> </p> <p> There's no longer any remnant of a DI Container. This is <a href="/2014/06/10/pure-di">Pure DI</a>. </p> <h3 id="b7d5b475bb88437ca9a39c6d2fbda35a"> Conclusion <a href="#b7d5b475bb88437ca9a39c6d2fbda35a" title="permalink">#</a> </h3> <p> Type-safe DI Containers are redundant. The simplest way to compose dependencies in a type-safe fashion is to write normal code, i.e. Pure DI. </p> <p> What about 'normal' DI Containers, though? These aren't type-safe, but <a href="/2012/11/06/WhentouseaDIContainer">may have their uses</a>. They represent a trade-off. For sufficiently complicated code bases, they may offer some benefits. </p> <p> I typically don't consider the trade-off worthwhile. The keywords in the above paragraph are 'sufficiently complicated'. Instead of writing complicated code, I favour simplicity: <a href="/code-that-fits-in-your-head">code that fits in my head</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. A type-safe DI Container as a tuple https://blog.ploeh.dk/2022/03/07/a-type-safe-di-container-as-a-tuple 2022-03-07T07:42:00+00:00 Mark Seemann <div id="post"> <p> <em>Tuples are DI Containers. With example code in C#.</em> </p> <p> This article is part of a series called <a href="/2022/01/10/type-safe-di-composition">Type-safe DI composition</a>. In the previous article, you saw <a href="/2022/02/21/a-type-safe-di-container-as-a-functor">a C# example of a type-safe DI Container as a functor</a>. In case it's not clear from the article that introduces the series, there's really no point to any of this. My motivation for writing the article is that readers sometimes ask me about topics such as DI Containers versus type safety, or DI Containers in functional programming. The goal of these articles is to make it painfully clear why I find such ideas moot. </p> <p> The previous article demonstrated how you can view a type-safe DI Container as a <a href="/2018/03/22/functors">functor</a>. The payload is a registry of services. You could introduce a specialised Parameter Object with each service given a name, but really, since <a href="https://ayende.com/blog/2886/building-an-ioc-container-in-15-lines-of-code">a DI container is little more than a dictionary keyed by type</a>, if you <a href="/2022/01/24/type-level-di-container-prototype">give each element of a tuple a unique type</a>, then a tuple of services is all you need. </p> <h3 id="47a88147593b4ef9a8721f4045b553ca"> Identity <a href="#47a88147593b4ef9a8721f4045b553ca" title="permalink">#</a> </h3> <p> In <a href="/2022/02/21/a-type-safe-di-container-as-a-functor">the previous article</a>, I asked the question: <em>Does <code>Container&lt;T&gt;</code> and its <code>Select</code> method form a lawful functor?</em> In other words, does it obey the functor laws? </p> <p> In the article, I just left the question dangling, so you might wonder if there's something fishy going on. In a sense, there is. </p> <p> The Container functor is simply the <a href="/2018/09/03/the-identity-functor">Identity functor</a> in disguise. Just imagine renaming <code>Container&lt;T&gt;</code> to <code>Identity&lt;T&gt;</code> and this should be clear. Since the Identity functor is lawful, the Container functor is also lawful. </p> <p> On the other hand, the Identity functor is redundant. It doesn't offer any additional capabilities over its payload. Anything you can do with the Identity functor's payload, you can do directly to the payload. An even stronger statement is that the Identity functor is isomorphic to its underlying payload. This is true also for <code>Container&lt;T&gt;</code>, which is isomorphic to <code>T</code>. This is clear from the definition of the class: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Container</span>(T&nbsp;<span style="color:#1f377f;">item</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item&nbsp;=&nbsp;item; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;Item&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;More&nbsp;members&nbsp;to&nbsp;follow...</span></pre> </p> <p> You can convert <em>any</em> <code>T</code> to a <code>Container&lt;T&gt;</code> by calling the constructor, and you can convert <em>any</em> <code>Container&lt;T&gt;</code> to a <code>T</code> value by reading the <code>Item</code> property. </p> <p> Then why have the Container at all? </p> <h3 id="2ab798ff8d8c452d92d4f0c4da12516a"> Tuple as a DI Container <a href="#2ab798ff8d8c452d92d4f0c4da12516a" title="permalink">#</a> </h3> <p> In the previous article, we left off with a container defined as <code>Container&lt;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&gt;</code>. It follows that the type of the Container's <code>Item</code> property is <code>(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)</code> - a tuple with three elements. </p> <p> This code example makes use of C# <a href="https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-tuples">tuple types</a>, which enables you to give each element in the tuple a name. For the tuple in question, the first element is called <code>rdb</code>, the next element <code>clock</code>, and the third <code>repo</code>. This makes the code that accesses these elements more readable, but is structurally unimportant. If you work in a language without this tuple feature, it doesn't change the conclusion in this article series. </p> <p> Instead of relying on <code>Container&lt;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&gt;</code>, the <code>CompositionRoot</code> class can rely on the unwrapped tuple: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&nbsp;container; <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">CompositionRoot</span>( &nbsp;&nbsp;&nbsp;&nbsp;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&nbsp;<span style="color:#1f377f;">container</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.container&nbsp;=&nbsp;container; }</pre> </p> <p> Its <code>Create</code> method directly accesses the tuple elements to create Controllers: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">object</span>&nbsp;<span style="color:#74531f;">Create</span>(ControllerContext&nbsp;<span style="color:#1f377f;">context</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(context&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(context)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;context.ActionDescriptor.ControllerTypeInfo; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(CalendarController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;CalendarController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.rdb, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.repo); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(HomeController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;HomeController(container.rdb); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ReservationsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationsController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.clock, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.rdb, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.repo); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(RestaurantsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;RestaurantsController(container.rdb); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ScheduleController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ScheduleController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.rdb, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.repo, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AccessControlList.FromUser(context.HttpContext.User)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;Unexpected&nbsp;controller&nbsp;type:&nbsp;</span>{t}<span style="color:#a31515;">.&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(context)); }</pre> </p> <p> Notice that instead of <code>container.Item.rdb</code>, <code>container.Item.repo</code>, and <code>container.Item.clock</code>, there's no redundant <code>Item</code> property. The <code>Create</code> method can directly access <code>container.rdb</code>, <code>container.repo</code>, and <code>container.clock</code>. </p> <h3 id="1714e2353b3349f7babbeea715058d5f"> Registration <a href="#1714e2353b3349f7babbeea715058d5f" title="permalink">#</a> </h3> <p> Not only did it become easier to <a href="/2010/09/29/TheRegisterResolveReleasepattern">resolve services</a> from the Container (i.e. the tuple) - registering services is also simpler: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">rdb</span>&nbsp;=&nbsp;CompositionRoot.CreateRestaurantDatabase(Configuration); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">po</span>&nbsp;=&nbsp;CompositionRoot.CreatePostOffice(Configuration,&nbsp;rdb); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">clock</span>&nbsp;=&nbsp;CompositionRoot.CreateClock(); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">repo</span>&nbsp;=&nbsp;CompositionRoot.CreateRepository(Configuration,&nbsp;po); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">container</span>&nbsp;=&nbsp;(rdb,&nbsp;clock,&nbsp;repo); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">compositionRoot</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompositionRoot(container); services.AddSingleton&lt;IControllerActivator&gt;(compositionRoot);</pre> </p> <p> Just create the services and put them in a tuple of the desired shape. No <em>query syntax</em> or other compiler tricks are required. Just write normal code. </p> <h3 id="ba588510ef1841aa8591f5885f4b04c5"> Conclusion <a href="#ba588510ef1841aa8591f5885f4b04c5" title="permalink">#</a> </h3> <p> The <code>Container&lt;T&gt;</code> class is just the Identity functor in disguise. It's redundant, so you can delete it and instead use a tuple, a record type, or a Parameter Object as your service registry. </p> <p> Are we done now, or can we simplify things even further? Read on. </p> <p> <strong>Next:</strong> <a href="/2022/03/14/type-safe-di-containers-are-redundant">Type-safe DI Containers are redundant</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Can one flatten a statically typed list? https://blog.ploeh.dk/2022/02/28/can-one-flatten-a-statically-typed-list 2022-02-28T06:58:00+00:00 Mark Seemann <div id="post"> <p> <em>What would be the type of a heterogeneously nested list?</em> </p> <p> Once again, I (inadvertently) managed to start a discussion on Twitter about static versus dynamic typing. I've <a href="/2021/08/09/am-i-stuck-in-a-local-maximum">touched on the topic before</a>, but my agenda is not to fan any flames - quite the contrary. I'm trying (nay, <em>struggling</em>) to <em>understand</em> the other side of the debate. </p> <p> This post isn't really about that, though, but in one of the threads spawned by my <a href="https://twitter.com/ploeh/status/1497261540445241350">original tweet</a>, <a href="https://twitter.com/tom_a_r_johnson">Tom Johnson</a> wrote: </p> <blockquote> <p> "One of my favourite examples: </p> <p> "What's the type of [[[3, 2], 7, [2, 4], 1], 0]? </p> <p> "What's the type of flatten, which takes that value and yields [3, 2, 7, 2, 4, 1, 0]?" </p> <footer><cite><a href="https://twitter.com/tom_a_r_johnson/status/1497384367156609027">Tom Johnson</a></cite></footer> </blockquote> <p> The type, it turns out, is straightforward. </p> <p> I'd like to be explicit about my agenda when writing this article. I'm not doing this to prove Tom Johnson wrong. In fact, I get the sense that he already knows the answer. Rather, I found it an interesting little exercise. </p> <h3 id="c37c2ce8c0154b8f9058ae47d8697ec8"> Syntax <a href="#c37c2ce8c0154b8f9058ae47d8697ec8" title="permalink">#</a> </h3> <p> First, we need to get one thing out of the way. In many languages, <code>[[[3, 2], 7, [2, 4], 1], 0]</code> isn't valid syntax. Even as a 'normal' list, syntax like <code>[3, 2, 7, 2, 4, 1, 0]</code> wouldn't be valid syntax in some languages. </p> <p> In <a href="https://www.haskell.org">Haskell</a> <code>[3, 2, 7, 2, 4, 1, 0]</code> would be valid, but it wouldn't be valid syntax in C#. And while it'd be valid syntax in <a href="https://fsharp.org">F#</a>, it wouldn't mean what it means in Haskell. The F# equivalent would be <code>[3; 2; 7; 2; 4; 1; 0]</code>. </p> <p> The point is that that I don't consider myself bound by the specific syntax <code>[[[3, 2], 7, [2, 4], 1], 0]</code>. I'm going to answer the question using Haskell, and in Haskell, that code doesn't parse. </p> <p> Instead, I'll use a data structure that represents the same data, but in a more verbose manner. </p> <h3 id="24df61de8afb498ab9d10f397e8d24f8"> Tree <a href="#24df61de8afb498ab9d10f397e8d24f8" title="permalink">#</a> </h3> <p> In one of the Twitter threads, <a href="https://lexi-lambda.github.io/">Alexis King</a> already gave the answer: </p> <blockquote> <p> "`flatten` is perfectly possible in Haskell, you just have to write a rose tree datatype, not use `[a]`." </p> <footer><cite><a href="https://twitter.com/lexi_lambda/status/1497339055629025283">Alexis King</a></cite></footer> </blockquote> <p> The standard <code>Tree a</code> in <a href="https://hackage.haskell.org/package/containers/docs/Data-Tree.html">Data.Tree</a>, however, doesn't seem to quite fit. Instead, we can use a <a href="https://en.wikipedia.org/wiki/Rose_tree">rose tree</a>. As Meertens wrote: </p> <blockquote> <p> "We consider trees whose internal nodes may fork into an arbitrary (natural) number of sub-trees. (If such a node has zero descendants, we still consider it internal.) Each external node carries a data item. No further information is stored in the tree; in particular, internal nodes are unlabelled." </p> <footer><cite><em>First Steps towards the Theory of Rose Trees</em>, Lambert Meertens, 1988</cite></footer> </blockquote> <p> With <em>unlabelled</em> nodes, we might draw Tom Johnson's 'list' like this: </p> <p> <img src="/content/binary/nested-list-as-tree.png" alt="A nested 'list' drawn as a tree."> </p> <p> I'll use the <code>Tree</code> data type introduced in the article <a href="/2019/09/09/picture-archivist-in-haskell">Picture archivist in Haskell</a>: </p> <p> <pre><span style="color:blue;">data</span>&nbsp;Tree&nbsp;a&nbsp;b&nbsp;=&nbsp;Node&nbsp;a&nbsp;[Tree&nbsp;a&nbsp;b]&nbsp;|&nbsp;Leaf&nbsp;b&nbsp;<span style="color:blue;">deriving</span>&nbsp;(<span style="color:#2b91af;">Eq</span>,&nbsp;<span style="color:#2b91af;">Show</span>,&nbsp;<span style="color:#2b91af;">Read</span>)</pre> </p> <p> If you would, you could define a type alias that has unlabelled internal nodes: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;MeertensTree&nbsp;=&nbsp;Tree&nbsp;<span style="color:blue;">()</span><br/></pre> </p> <p> I'm not really going to bother doing that, though. I'm just going to create a <code>Tree () b</code> value. </p> <p> Here we go: </p> <p> <pre>&gt; l = Node () [Node () [Node () [Leaf 3, Leaf 2], Leaf 7, Node () [Leaf 2, Leaf 4], Leaf 1], Leaf 0] &gt; :t l l :: Num b =&gt; Tree () b</pre> </p> <p> You could probably come up with a more succinct syntax to create trees like this in code, but I'm assuming that in 'reality', if you have the need to flatten nested lists, it'll be a values that arrive at the boundary of the application... </p> <h3 id="9f83ac5fc78e47d0be64cadfe5d43f4c"> Flattening <a href="#9f83ac5fc78e47d0be64cadfe5d43f4c" title="permalink">#</a> </h3> <p> Can you flatten the 'list' <code>l</code>? </p> <p> Yes, no problem. The <code>Tree a b</code> data type is an instance of various type classes, among these <code>Foldable</code>: </p> <p> <pre><span style="color:blue;">instance</span>&nbsp;<span style="color:blue;">Foldable</span>&nbsp;(<span style="color:blue;">Tree</span>&nbsp;a)&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;foldMap&nbsp;=&nbsp;bifoldMap&nbsp;mempty</pre> </p> <p> You can see the full definition of <code>bifoldMap</code> and its dependencies in <a href="/2019/09/09/picture-archivist-in-haskell">the article that introduces the type</a>. </p> <p> One of the functions available via <code>Foldable</code> is <code>toList</code>, which is just what you need: </p> <p> <pre>&gt; toList l [3,2,7,2,4,1,0]</pre> </p> <p> This is the result required by Tom Johnson. </p> <h3 id="4bf861c4bd5a49fbab9426fe55e8ec3f"> Summary <a href="#4bf861c4bd5a49fbab9426fe55e8ec3f" title="permalink">#</a> </h3> <p> In short, the answer to the question: <em>"What's the type of [[[3, 2], 7, [2, 4], 1], 0]?"</em> is: <code>Num b =&gt; Tree () b</code>, an example of which might be <code>Tree () Integer</code>. You could also call it <code>MeertensTree Integer</code>. </p> <p> Likewise, the type of the requested <code>flatten</code> function is <code>toList :: Foldable t =&gt; t a -&gt; [a]</code>. </p> </div> <div id="comments"> <hr/> <h2 id="comments-header">Comments</h2> <div class="comment" id="c3ed1ef693ce4c5a85c612cdbbc85cd8"> <div class="comment-author">Michael Hensler</div> <div class="comment-content"> <p> He appears to be using JavaScript and the solution is trivial in TypeScript, so he must not have looked too hard before claiming that statically typed languages cannot handle this scenario. He also kept moving the goalposts (It needs to use list syntax! It needs to support heterogeneous lists!), but even the most naïve attempt in TypeScript handles those as well. </p> <pre>type Nested&lt;T&gt; = (Nested&lt;T&gt; | T)[]; const flatten = &lt;T&gt;(val: Nested&lt;T&gt;): T[] => val.reduce( (r: T[], v) =&gt; [...r, ...(Array.isArray(v) ? flatten(v) : [v])], [] ); const nested = [[[3, 2], 7, [2, 4], 1], 0]; const result = flatten(nested); console.log(result); // [3, 2, 7, 2, 4, 1, 0] const silly: Nested&lt;number | string | { name: string }&gt; = [ [[3, 2], 1], "cheese", { name: "Fred" }, ]; const sillyResult = flatten(silly); console.log(sillyResult); // [3, 2, 1, "cheese", {"name": "Fred"}]</pre> <p> TypeScript types can also maintain the order of the types of elements in the flattened list. <a href="https://catchts.com/flatten">How to flatten a tuple type in TypeScript?</a> gives a solution capable of handling that, though it is certainly more complex than the version above. </p> </div> <div class="comment-date">2022-03-01 03:48 UTC</div> </div> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. A type-safe DI Container as a functor https://blog.ploeh.dk/2022/02/21/a-type-safe-di-container-as-a-functor 2022-02-21T06:37:00+00:00 Mark Seemann <div id="post"> <p> <em>Decoupling the registry of services from the container. An ongoing C# example.</em> </p> <p> This article is part of a series called <a href="/2022/01/10/type-safe-di-composition">Type-safe DI composition</a>. In the previous article, you saw <a href="/2022/02/07/nested-type-safe-di-containers">a C# example of a type-safe, nested DI Container</a>. In case it's not clear from the article that introduces the series, there's really no point to any of this. My motivation for writing the article is that readers sometimes ask me about topics such as DI Containers versus type safety, or DI Containers in functional programming. The goal of these articles is to make it painfully clear why I find such ideas moot. </p> <p> In the previous article, you saw how you can use container nesting to implement a type-safe container of arbitrary arity. You only need these generic containers: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span> <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>&gt; <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>&gt;</pre> </p> <p> You can achieve arities higher than two by nesting containers. For example, you can <a href="/2010/09/29/TheRegisterResolveReleasepattern">register</a> three services by nesting one container inside another: <code>Container&lt;T1,&nbsp;Container&lt;T2,&nbsp;T3&gt;&gt;</code>. Higher arities require more nesting. See the <a href="/2022/02/07/nested-type-safe-di-containers">previous article</a> for an example with five services. </p> <h3 id="c0c1df1b436c49a79f1ea5aef2a9d251"> Decoupling the container from the registry <a href="#c0c1df1b436c49a79f1ea5aef2a9d251" title="permalink">#</a> </h3> <p> How did I get the idea of nesting the containers? </p> <p> It started as I was examining the constructor of the <code>CompositionRoot</code> class: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Container&lt;IConfiguration,&nbsp;Container&lt;Container&lt;Container&lt;IRestaurantDatabase,&nbsp;IPostOffice&gt;,&nbsp;IClock&gt;,&nbsp;IReservationsRepository&gt;&gt;&nbsp;container; <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">CompositionRoot</span>(Container&lt;IConfiguration,&nbsp;Container&lt;Container&lt;Container&lt;IRestaurantDatabase,&nbsp;IPostOffice&gt;,&nbsp;IClock&gt;,&nbsp;IReservationsRepository&gt;&gt;&nbsp;<span style="color:#1f377f;">container</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.container&nbsp;=&nbsp;container; }</pre> </p> <p> Those are, indeed, wide lines of code. No <a href="/2019/11/04/the-80-24-rule">80x24 box</a> here. If you ignore all the container nesting, you can tell that the container contains five services: <ul> <li><code>IConfiguration</code></li> <li><code>IRestaurantDatabase</code></li> <li><code>IPostOffice</code></li> <li><code>IClock</code></li> <li><code>IReservationsRepository</code></li> </ul> What may not be immediately clear, however, is that only three of those are required by <code>CompositionRoot</code>: <ul> <li><code>IRestaurantDatabase</code></li> <li><code>IClock</code></li> <li><code>IReservationsRepository</code></li> </ul> The <code>IConfiguration</code> and <code>IPostOffice</code> services are only present because they were required to create some of the other services. <code>CompositionRoot</code> never directly uses these two services. In other words, there's a leaky abstraction somewhere. </p> <p> It'd be more in spirit with the <a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion Principle</a> (DIP) and the <a href="https://en.wikipedia.org/wiki/Interface_segregation_principle">Interface Segregation Principle</a> (ISP) if the constructor required only the services it needs. </p> <p> On the other hand, it's easiest to create the container from its constituent elements if you can pass already-registered services along when registering other services: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">container</span>&nbsp;=&nbsp;Container.Empty &nbsp;&nbsp;&nbsp;&nbsp;.Register(Configuration) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreateRestaurantDatabase) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreatePostOffice) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreateClock()) &nbsp;&nbsp;&nbsp;&nbsp;.Register((<span style="color:#1f377f;">conf</span>,&nbsp;<span style="color:#1f377f;">cont</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompositionRoot.CreateRepository(conf,&nbsp;cont.Item1.Item2)); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">compositionRoot</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompositionRoot(container); services.AddSingleton&lt;IControllerActivator&gt;(compositionRoot);</pre> </p> <p> I realised that the container needed a way to remove services from the public API. And it hit me that it'd be easier if I separated the container from its registry of services. If I did that, I could define a <em>single</em> generic <code>Container&lt;T&gt;</code> and even make it a <a href="/2018/03/22/functors">functor</a>. The payload could be a custom Parameter Object, but could also just be a tuple of services. </p> <p> From <a href="https://thinkingwithtypes.com">Thinking with Types</a> I knew that you can reduce all <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">algebraic data types</a> to canonical representations of <a href="/2018/06/11/church-encoded-either">Eithers</a> and tuples. </p> <p> A triple, for example, can be modelled as a <code>Tuple&lt;T1, Tuple&lt;T2, T3&gt;&gt;</code> or <code>Tuple&lt;Tuple&lt;T1, T2&gt;, T3&gt;</code>, a quadruple as e.g. <code>Tuple&lt;Tuple&lt;T1, T2&gt;, Tuple&lt;T3, T4&gt;&gt;</code>, etcetera. </p> <p> Connecting those dots, I also realised that as an intermediary step I could nest the containers. It's really unnecessary, though, so let's proceed to simplify the code. </p> <h3 id="6e6880e3ca98497d87473981d084d43f"> A Container functor <a href="#6e6880e3ca98497d87473981d084d43f" title="permalink">#</a> </h3> <p> Instead of a <code>Container&lt;T1, T2&gt;</code> in addition to a <code>Container&lt;T1&gt;</code>, you only need the single-arity container: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Container</span>(T&nbsp;<span style="color:#1f377f;">item</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item&nbsp;=&nbsp;item; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;Item&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;More&nbsp;members&nbsp;to&nbsp;follow...</span></pre> </p> <p> Apart from overriding <code>Equals</code> and <code>GetHashCode</code>, the only member is <code>Select</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Container&lt;TResult&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">TResult</span>&gt;(Func&lt;T,&nbsp;TResult&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(selector&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(selector)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Container&lt;TResult&gt;(selector(Item)); }</pre> </p> <p> This is a straightforward <code>Select</code> implementation, making <code>Container&lt;T&gt;</code> a functor. </p> <h3 id="140bf408620c4c9aa3bd2d4480f333a2"> Usage <a href="#140bf408620c4c9aa3bd2d4480f333a2" title="permalink">#</a> </h3> <p> You can use the <code>Select</code> method to incrementally build the desired container: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">container</span>&nbsp;=&nbsp;Container.Empty.Register(Configuration) &nbsp;&nbsp;&nbsp;&nbsp;.Select(<span style="color:#1f377f;">conf</span>&nbsp;=&gt;&nbsp;(conf,&nbsp;rdb:&nbsp;CompositionRoot.CreateRestaurantDatabase(conf))) &nbsp;&nbsp;&nbsp;&nbsp;.Select(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;(t.conf,&nbsp;t.rdb,&nbsp;po:&nbsp;CompositionRoot.CreatePostOffice(t.conf,&nbsp;t.rdb))) &nbsp;&nbsp;&nbsp;&nbsp;.Select(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;(t.conf,&nbsp;t.rdb,&nbsp;t.po,&nbsp;clock:&nbsp;CompositionRoot.CreateClock())) &nbsp;&nbsp;&nbsp;&nbsp;.Select(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;(t.conf,&nbsp;t.rdb,&nbsp;t.po,&nbsp;t.clock,&nbsp;repo:&nbsp;CompositionRoot.CreateRepository(t.conf,&nbsp;t.po))); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">compositionRoot</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompositionRoot(container); services.AddSingleton&lt;IControllerActivator&gt;(compositionRoot);</pre> </p> <p> The syntax is awkward, since you need to pass a tuple along to the next step, in which you need to access each of the tuple's elements, only to create a bigger tuple, and so on. </p> <p> While it does get the job done, we can do better. </p> <h3 id="176a52591fd8439e90e747ee96edc695"> Query syntax <a href="#176a52591fd8439e90e747ee96edc695" title="permalink">#</a> </h3> <p> Instead of using method-call syntax to chain all these service registrations together, you can take advantage of C#'s <em>query syntax</em> which lights up for any functor: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">container</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;conf&nbsp;<span style="color:blue;">in</span>&nbsp;Container.Empty.Register(Configuration) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;rdb&nbsp;=&nbsp;CompositionRoot.CreateRestaurantDatabase(conf) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;po&nbsp;=&nbsp;CompositionRoot.CreatePostOffice(conf,&nbsp;rdb) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;clock&nbsp;=&nbsp;CompositionRoot.CreateClock() &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;repo&nbsp;=&nbsp;CompositionRoot.CreateRepository(conf,&nbsp;po) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;(conf,&nbsp;rdb,&nbsp;po,&nbsp;clock,&nbsp;repo); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">compositionRoot</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompositionRoot(container); services.AddSingleton&lt;IControllerActivator&gt;(compositionRoot);</pre> </p> <p> In both cases, the <code>container</code> object has the type <code>Container&lt;(IConfiguration&nbsp;conf,&nbsp;IRestaurantDatabase&nbsp;rdb,&nbsp;IPostOffice&nbsp;po,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&gt;</code>, which is still quite the mouthful. Now, however, we can do something about it. </p> <h3 id="dea37fc7697046bc8d8c6ba881d34890"> DIP and ISP applied <a href="#dea37fc7697046bc8d8c6ba881d34890" title="permalink">#</a> </h3> <p> The <code>CompositionRoot</code> class only needs three services, so its constructor should ask for those, and no more: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Container&lt;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&gt; &nbsp;&nbsp;&nbsp;&nbsp;container; <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">CompositionRoot</span>( &nbsp;&nbsp;&nbsp;&nbsp;Container&lt;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&gt;&nbsp;<span style="color:#1f377f;">container</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.container&nbsp;=&nbsp;container; }</pre> </p> <p> With that injected <code>container</code> it can implement <code>Create</code> like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">object</span>&nbsp;<span style="color:#74531f;">Create</span>(ControllerContext&nbsp;<span style="color:#1f377f;">context</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(context&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(context)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;context.ActionDescriptor.ControllerTypeInfo; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(CalendarController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;CalendarController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item.rdb, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item.repo); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(HomeController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;HomeController(container.Item.rdb); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ReservationsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationsController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item.clock, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item.rdb, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item.repo); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(RestaurantsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;RestaurantsController(container.Item.rdb); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ScheduleController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ScheduleController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item.rdb, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item.repo, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AccessControlList.FromUser(context.HttpContext.User)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;Unexpected&nbsp;controller&nbsp;type:&nbsp;</span>{t}<span style="color:#a31515;">.&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(context)); }</pre> </p> <p> That's more readable, although the intermediary <code>Item</code> object doesn't seem to do much work... </p> <p> You can create a <code>container</code> with the desired type like this: </p> <p> <pre>Container&lt;(IRestaurantDatabase&nbsp;rdb,&nbsp;IClock&nbsp;clock,&nbsp;IReservationsRepository&nbsp;repo)&gt;&nbsp;<span style="color:#1f377f;">container</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;conf&nbsp;<span style="color:blue;">in</span>&nbsp;Container.Empty.Register(Configuration) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;rdb&nbsp;=&nbsp;CompositionRoot.CreateRestaurantDatabase(conf) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;po&nbsp;=&nbsp;CompositionRoot.CreatePostOffice(conf,&nbsp;rdb) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;clock&nbsp;=&nbsp;CompositionRoot.CreateClock() &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;repo&nbsp;=&nbsp;CompositionRoot.CreateRepository(conf,&nbsp;po) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;(rdb,&nbsp;clock,&nbsp;repo); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">compositionRoot</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompositionRoot(container); services.AddSingleton&lt;IControllerActivator&gt;(compositionRoot);</pre> </p> <p> Notice that the only difference compared to earlier is that the <code>select</code> expression only involves the three required services: <code>rdb</code>, <code>clock</code>, and <code>repo</code>. </p> <h3 id="0cf421420e044b6fb66292689f987d13"> Conclusion <a href="#0cf421420e044b6fb66292689f987d13" title="permalink">#</a> </h3> <p> This seems cleaner than before, but perhaps you're left with a nagging doubt: Why is the <code>Container&lt;T&gt;</code> class even required? What value does its <code>Item</code> property provide? </p> <p> And perhaps another question is also in order: Does the <code>Select</code> method shown even define a lawful functor? </p> <p> Read on. </p> <p> <strong>Next:</strong> <a href="/2022/03/07/a-type-safe-di-container-as-a-tuple">A type-safe DI Container as a tuple</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. A conditional sandwich example https://blog.ploeh.dk/2022/02/14/a-conditional-sandwich-example 2022-02-14T07:44:00+00:00 Mark Seemann <div id="post"> <p> <em>An F# example of reducing a workflow to an impureim sandwich.</em> </p> <p> The most common reaction to the <a href="/2020/03/02/impureim-sandwich">impureim sandwich</a> architecture (also known as <a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">functional core, imperative shell</a>) is one of incredulity. How does this way of organising code generalise to arbitrary complexity? </p> <p> The short answer is that it doesn't. Given <em>sufficient complexity</em>, you may not be able to 1. gather all data with impure queries, 2. call a pure function, and 3. apply the return value via impure actions. The question is: How much complexity is required before you have to give up on the impureim sandwich? </p> <p> <img src="/content/binary/sandwich-transition-free.png" alt="Axis with sandwich to the left, free monad to the right, and a tentative transition zone in between, but biased to the right."> </p> <p> There's probably a fuzzy transition zone where the sandwich may still apply, but where it begins to be questionable whether it's beneficial. In my experience, this transition seems to lie further to the right than most people think. </p> <p> Once you have to give up on the impureim sandwich, in functional programming you may resort to using <a href="/2017/08/07/f-free-monad-recipe">free monads</a>. In object-oriented programming, you may use <a href="/dippp">Dependency Injection</a>. Depending on language and paradigm, still more options may be available. </p> <p> My experience is mostly with web-based systems, but in that context, I find that a surprisingly large proportion of problems can be rephrased and organised in such a way that the impureim sandwich architecture applies. Actually, I surmise that <em>most</em> problems can be addressed in that way. </p> <p> I am, however, often looking for good examples. As I wrote in <a href="/2017/02/02/dependency-rejection#36c724b49f614104842c47909cd9c916">a comment</a> to <a href="/2017/02/02/dependency-rejection">Dependency rejection</a>: </p> <blockquote> <p> "I'd welcome a simplified, but still concrete example where the impure/pure/impure sandwich described here isn't going to be possible." </p> </blockquote> <p> Such examples are, unfortunately, rare. While real production code may seem like an endless supply of examples, production code often contains irrelevant details that obscure the essence of the case. Additionally, production code is often proprietary, so I can't share it. </p> <p> In 2019 <a href="https://www.relativisticramblings.com/">Christer van der Meeren</a> kindly supplied an example problem that <a href="/2019/12/02/refactoring-registration-flow-to-functional-architecture">I could refactor</a>. Since then, there's been a dearth of more examples. Until now. </p> <p> I recently ran into another fine example of a decision flow that at first glance seemed a poor fit for the <em>functional core, imperative shell</em> architecture. What follows is, actually, production code, here reproduced with the kind permission of <a href="https://www.criipto.com/">Criipto</a>. </p> <h3 id="e90c1b9373854c988f5c7d4fe21f90ee"> Create a user if it doesn't exist <a href="#e90c1b9373854c988f5c7d4fe21f90ee" title="permalink">#</a> </h3> <p> As I've <a href="/2022/01/03/to-id-or-not-to-id">previously touched on</a>, I'm helping Criipto integrate with the <a href="https://fusebit.io/docs/reference/fusebit-http-api/">Fusebit API</a>. This API has a user model where you can create users in the Fusebit services. Once you've created a user, a client can log on as that user and access the resources available to her, him, or it. There's an underlying security model that controls all of that. </p> <p> Criipto's users may not all be provisioned as users in the Fusebit API. If they need to use the Fusebit system, we'll provision them just in time. On the other hand, there's no reason to create the user if it already exists. </p> <p> But it gets more complicated than that. To fit our requirements, the user must have an associated <em>issuer</em>. This is another Fusebit resource that we may have to provision if it doesn't already exist. </p> <p> The desired logic may be easier to follow if visualised as a flowchart. </p> <p> <img src="/content/binary/flowchart-to-create-fusebit-user.png" alt="Flowchart that illustrates how to provision a Fusebit user."> </p> <p> The user must have an <em>issuer</em>, but an appropriate issuer may already exist. If it doesn't, we must create the issuer before we create the user. </p> <p> At first blush this seems like a workflow that doesn't fit the impureim sandwich architecture. After all, you should only check for the existence of the issuer if you find that the user doesn't exist. There's a decision between the first and second impure query. </p> <p> Can we resolve this problem and implement the functionality as an impureim sandwich? </p> <h3 id="26f6a40a12534d349f556fb67c41e945"> Speculative prefetching <a href="#26f6a40a12534d349f556fb67c41e945" title="permalink">#</a> </h3> <p> When looking for ways to apply the <em>functional core, imperative shell</em> architecture, it often pays to take a step back and look at a slightly larger picture. Another way to put it is that you should think less procedurally, and more declaratively. A flowchart like the above is essentially procedural. It may prevent you from seeing other opportunities. </p> <p> One of the reasons I like functional programming is that it forces me to think in a more declarative way. This helps me identify better abstractions than I might otherwise be able to think of. </p> <p> The above flowchart is representative of the most common counterargument I hear: The impureim sandwich doesn't work if the code has to make a decision about a secondary query based on the result of an initial query. This is also what's at stake here. The result of the <em>user exists</em> query determines whether the program should query about the issuer. </p> <p> The assumption is that since the user is supposed to have an issuer, if the user exists, the issuer must also exist. </p> <p> Even so, would it hurt so much to query the Fusebit API up front about the issuer? </p> <p> Perhaps you react to such a suggestion with distaste. After all, it seems wasteful. Why query a web service if you don't need the result? And what about performance? </p> <p> Whether or not this is wasteful depends on what kind of waste you measure. If you measure bits transmitted over the network, then yes, you may see this measure increase. </p> <p> It may not be as bad as you think, though. Perhaps the HTTP <code>GET</code> request you're about to make has a cacheable result. Perhaps the result is already waiting in your proxy server's RAM. </p> <p> Neither the Fusebit HTTP API's <em>user</em> resources nor its <em>issuer</em> resources, however, come with cache headers, so this last argument doesn't apply here. I still included it above because it's worth taking into account. </p> <p> Another typical performance consideration is that this kind of potentially redundant traffic will degrade performance. Perhaps. As usual, if that's a concern: measure. </p> <p> Querying the API whether a user exists is independent of the query to check if an issuer exists. This means that you could perform the two queries in parallel. Depending on the total load on the system, the difference between one HTTP request and two concurrent requests may be negligible. (It could still impact overall system performance if the system is already running close to capacity, so this isn't always a good strategy. Often, however, it's not really an issue.) </p> <p> A third consideration is the statistical distribution of pathways through the system. If you consider the flowchart above, it indicates a <a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a> of <em>3</em>; there are three distinct pathways. </p> <p> If, however, it turns out that in 95 percent of cases the user <em>doesn't</em> exist, you're going to have to perform the second query (for issuer) anyway, then the difference between prefetching and conditional querying is minimal. </p> <p> While some would consider this 'cheating', when aiming for the impureim sandwich architecture, these are all relevant questions to ponder. It often turns out that you <em>can</em> fetch all the data before passing them to a pure function. It may entail 'wasting' some electrons on queries that turn out to be unnecessary, but it may still be worth doing. </p> <p> There's another kind of waste worth considering. This is the waste in <em>developer hours</em> if you write code that's harder to maintain than it has to be. As I recently described in an article titled <a href="https://stackoverflow.blog/2022/01/03/favor-real-dependencies-for-unit-testing/">Favor real dependencies for unit testing</a>, the more you use functional programming, the less test maintenance you'll have. </p> <p> Keep in mind that the scenario in this article is a server-to-server interaction. How much would a bit of extra bandwidth cost, versus wasted programmer hours? </p> <p> If you can substantially simplify the code at the cost of a few dollars of hardware or network infrastructure, it's often a good trade-off. </p> <h3 id="284c71bc67ef4958b855f57b892fd842"> Referential integrity <a href="#284c71bc67ef4958b855f57b892fd842" title="permalink">#</a> </h3> <p> The above flowchart implies a more subtle assumption that turns out to not hold in practice. The assumption is that all users in the system have been created the same: that all users are associated with an issuer. Thus, according to this assumption, if the user exists, then so must the issuer. </p> <p> This turns out to be a false assumption. The Fusebit HTTP API doesn't enforce <a href="https://en.wikipedia.org/wiki/Referential_integrity">referential integrity</a>. You can create a user with an issuer that doesn't exist. When creating a user, you supply only the issuer ID (a string), but the API doesn't check that an issuer with that ID exists. </p> <p> Thus, just because a user exists you can't be sure that its associated issuer exists. To be sure, you'd have to check. </p> <p> But this means that you'll have to perform two queries after all. The angst from the previous section turns out to be irrelevant. The flowchart is wrong. </p> <p> Instead, you have two independent, but potentially parallelisable, processes: </p> <p> <img src="/content/binary/parallel-flowchart-to-create-fusebit-user-and-issuer.png" alt="Flowchart showing the actual parallel nature of Fusebit user provisioning."> </p> <p> You can't always be that lucky when you consider how to make requirements fit the impureim sandwich mould, but this is beginning to look really promising. Each of these two processes is near-trivial. </p> <h3 id="6622f662e19243a198475bde42d624bd"> Idempotence <a href="#6622f662e19243a198475bde42d624bd" title="permalink">#</a> </h3> <p> Really, what's actually required is an <a href="https://en.wikipedia.org/wiki/Idempotence">idempotent</a> <em>create</em> action. As the <a href="/ref/rest-cookbook">RESTful Web Services Cookbook</a> describes, all HTTP verbs <em>except</em> <code>POST</code> should be regarded as idempotent in a well-designed API. Alas, creating users and issuers are (naturally) done with <code>POST</code> requests, so these operations aren't naturally idempotent. </p> <p> In functional programming you often <a href="/2016/09/26/decoupling-decisions-from-effects">decouple decisions from effects</a>. In order to be able to do that here, I created this <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/discriminated-unions">discriminated union</a>: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;Idempotent&lt;&#39;a&gt;&nbsp;=&nbsp;UpToDate&nbsp;|&nbsp;Update&nbsp;<span style="color:blue;">of</span>&nbsp;&#39;a</pre> </p> <p> This type is isomorphic to <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/options">option</a>, but I found it worthwhile to introduce a distinct type for this particular purpose. Usually, if a query returns, say <code>UserData option</code>, you'd interpret the <code>Some</code> case as indicating that the user exists, and the <code>None</code> case as indicating that the user doesn't exist. </p> <p> Here, I wanted the 'populated' case to indicate that an <code>Update</code> action is required. If I'd used <code>option</code>, then I would have had to map the user-doesn't-exist case to a <code>Some</code> value, and the user-exists case to a <code>None</code> value. I though that this might be confusing to other programmers, since it'd go against the usual <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a> use of the type. </p> <p> That's the reason I created a custom type. </p> <p> The <code>UpToDate</code> case indicates that the value exists and is up to date. The <code>Update</code> case is worded in the imperative to indicate that the value (of type <code>'a</code>) should be updated. </p> <h3 id="6c8043d3335840919df68562d57a91e5"> Establish <a href="#6c8043d3335840919df68562d57a91e5" title="permalink">#</a> </h3> <p> The purpose of this entire exercise is to <em>establish</em> that a user (and issuer) exists. It's okay if the user already exists, but if it doesn't, we should create it. </p> <p> I mulled over the terminology and liked the verb <em>establish</em>, to the consternation of many Twitter users. </p> <blockquote> <p> CreateUserIfNotExists is a crude name 🤢 </p> <p> How about EstablishUser instead? </p> <p> "Establish" can both mean to "set up on a firm or permanent basis" and "show (something) to be true or certain by determining the facts". That seems to say the same in a more succinct way 👌 </p> <footer><cite><a href="https://twitter.com/ploeh/status/1471123230203199491">Me, on Twitter</a></cite></footer> </blockquote> <p> Just read the comments to see how divisive that little idea is. Still, I decided to define a function called <code>establish</code> to convert a Boolean and an <code>'a</code> value to an <code>Idempotent&lt;&#39;a&gt;</code> value. </p> <p> Don't forget the purpose of this entire exercise. The benefit that the impureim sandwich architecture can bring is that it enables you to drain the impure parts of the sandwich of logic. <a href="/2015/05/07/functional-design-is-intrinsically-testable">Pure functions are intrinsically testable</a>, so the more you define decisions and algorithms as pure functions, the more testable the code will be. </p> <p> It's even better when you can make the testable functions generic, because reusable functions has the potential to reduce cognitive load. Once a reader learns and understands an abstraction, it stops being much of a cognitive load. </p> <p> The functions to create and manipulate <code>Idempotent&lt;&#39;a&gt;</code> values should be covered by automated tests. The behaviour is quite trivial, though, so to increase coverage we can write the tests as properties. The code base in question already uses <a href="https://fscheck.github.io/FsCheck/">FsCheck</a>, so I just went with that: </p> <p> <pre>[&lt;Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``Idempotent.establish&nbsp;returns&nbsp;UpToDate``&nbsp;(x&nbsp;:&nbsp;int)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;Idempotent.establish&nbsp;x&nbsp;<span style="color:blue;">true</span> &nbsp;&nbsp;&nbsp;&nbsp;UpToDate&nbsp;=!&nbsp;actual [&lt;Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``Idempotent.establish&nbsp;returns&nbsp;Update``&nbsp;(x&nbsp;:&nbsp;string)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;Idempotent.establish&nbsp;x&nbsp;<span style="color:blue;">false</span> &nbsp;&nbsp;&nbsp;&nbsp;Update&nbsp;x&nbsp;=!&nbsp;actual</pre> </p> <p> These two properties also use <a href="https://github.com/SwensenSoftware/Unquote">Unquote</a> for assertions. The <code>=!</code> operator means <em>should equal</em>, so you can read an expression like <code>UpToDate&nbsp;=!&nbsp;actual</code> as <em>UpToDate should equal actual</em>. </p> <p> This describes the entire behaviour of the <code>establish</code> function, which is implemented this way: </p> <p> <pre><span style="color:green;">//&nbsp;&#39;a&nbsp;-&gt;&nbsp;bool&nbsp;-&gt;&nbsp;Idempotent&lt;&#39;a&gt;</span> <span style="color:blue;">let</span>&nbsp;establish&nbsp;x&nbsp;isUpToDate&nbsp;=&nbsp;<span style="color:blue;">if</span>&nbsp;isUpToDate&nbsp;<span style="color:blue;">then</span>&nbsp;UpToDate&nbsp;<span style="color:blue;">else</span>&nbsp;Update&nbsp;x</pre> </p> <p> About as trivial as it can be. Unsurprising code is good. </p> <h3 id="af0781e5c14f4044bb46a885c7960870"> Fold <a href="#af0781e5c14f4044bb46a885c7960870" title="permalink">#</a> </h3> <p> The <code>establish</code> function affords a way to create <code>Idempotent</code> values. It'll also be useful with a function to <a href="/2019/02/04/how-to-get-the-value-out-of-the-monad">get the value out of the container</a>, so to speak. While you can always <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/pattern-matching">pattern match</a> on an <code>Idempotent</code> value, that'd introduce decision logic into the code that does that. </p> <p> The goal is to cover as much decision logic as possible by tests so that we can leave the overall impureim sandwich as an untested declarative composition - a <a href="http://xunitpatterns.com/Humble%20Object.html">Humble Object</a>, if you will. It'd be appropriate to introduce a reusable function (covered by tests) that can fulfil that role. </p> <p> We need the so-called <em>case analysis</em> of <code>Idempotent&lt;&#39;a&gt;</code>. In other terminology, this is also known as the <a href="/2019/04/29/catamorphisms">catamorphism</a>. Since <code>Idempotent&lt;&#39;a&gt;</code> is isomorphic to <code>option</code> (also known as <em>Maybe</em>), the catamorphism is also isomorphic to the <a href="/2019/05/20/maybe-catamorphism">Maybe catamorphism</a>. While we expect no surprises, we can still cover the function with automated tests: </p> <p> <pre>[&lt;Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``Idempotent.fold&nbsp;when&nbsp;up-to-date``&nbsp;(expected&nbsp;:&nbsp;DateTimeOffset)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Idempotent.fold&nbsp;(<span style="color:blue;">fun</span>&nbsp;_&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;DateTimeOffset.MinValue)&nbsp;expected&nbsp;UpToDate &nbsp;&nbsp;&nbsp;&nbsp;expected&nbsp;=!&nbsp;actual [&lt;Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``Idempotent.fold&nbsp;when&nbsp;update&nbsp;required``&nbsp;(x&nbsp;:&nbsp;TimeSpan)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;f&nbsp;(ts&nbsp;:&nbsp;TimeSpan)&nbsp;=&nbsp;ts.TotalHours&nbsp;+&nbsp;float&nbsp;ts.Minutes &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;Update&nbsp;x&nbsp;|&gt;&nbsp;Idempotent.fold&nbsp;f&nbsp;1.1 &nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;x&nbsp;=!&nbsp;actual</pre> </p> <p> The most common catamorphisms are idiomatically called <code>fold</code> in F#, so that's what I called it as well. </p> <p> The first property states that when the <code>Idempotent</code> value is already <code>UpToDate</code>, <code>fold</code> simply returns the 'fallback value' (here called <code>expected</code>) and the function doesn't run. </p> <p> When the <code>Idempotent</code> is an <code>Update</code> value, the function <code>f</code> runs over the contained value <code>x</code>. </p> <p> The implementation hardly comes as a surprise: </p> <p> <pre><span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;&#39;b)&nbsp;-&gt;&nbsp;&#39;b&nbsp;-&gt;&nbsp;Idempotent&lt;&#39;a&gt;&nbsp;-&gt;&nbsp;&#39;b</span> <span style="color:blue;">let</span>&nbsp;fold&nbsp;f&nbsp;onUpToDate&nbsp;=&nbsp;<span style="color:blue;">function</span> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;UpToDate&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;onUpToDate &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Update&nbsp;x&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;f&nbsp;x</pre> </p> <p> Both <code>establish</code> and <code>fold</code> are general-purpose functions. I needed one more specialised function before I could compose a workflow to create a Fusebit user if it doesn't exist. </p> <h3 id="d0dada3f342f42df93197f777ac94712"> Checking whether an issuer exists <a href="#d0dada3f342f42df93197f777ac94712" title="permalink">#</a> </h3> <p> As I've <a href="/2022/01/03/to-id-or-not-to-id">previously mentioned</a>, I'd already developed a set of modules to interact with the Fusebit API. One of these was a function to read an issuer. This <code>Issuer.get</code> action returns a <code>Task&lt;Result&lt;IssuerData, HttpResponseMessage&gt;&gt;</code>. </p> <p> The <code>Result</code> value will only be an <code>Ok</code> value if the issuer exists, but we can't conclude that any <code>Error</code> value indicates a missing resource. An <code>Error</code> may also indicate a genuine HTTP error. </p> <p> A function to translate a <code>Result&lt;IssuerData, HttpResponseMessage&gt;</code> value to a <code>Result&lt;bool, HttpResponseMessage&gt;</code> by examining the <code>HttpResponseMessage</code> is just complex enough (cyclomatic complexity <em>3</em>) to warrant unit test coverage. Here I just went with some parametrised tests rather than FsCheck properties. </p> <p> The first test asserts that when the result is <code>Ok</code> it translates to <code>Ok true</code>: </p> <p> <pre>[&lt;Theory&gt;] [&lt;InlineData&nbsp;(<span style="color:#a31515;">&quot;https://example.com&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;DN&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;https://example.net&quot;</span>)&gt;] [&lt;InlineData&nbsp;(<span style="color:#a31515;">&quot;https://example.org/id&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;lga&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;https://example.gov/jwks&quot;</span>)&gt;] [&lt;InlineData&nbsp;(<span style="color:#a31515;">&quot;https://example.com/id&quot;</span>,&nbsp;<span style="color:blue;">null</span>,&nbsp;<span style="color:#a31515;">&quot;https://example.org/.jwks&quot;</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``Issuer&nbsp;exists``&nbsp;iid&nbsp;dn&nbsp;jwks&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;issuer&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;Uri&nbsp;iid &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DisplayName&nbsp;=&nbsp;dn&nbsp;|&gt;&nbsp;Option.ofObj &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PKA&nbsp;=&nbsp;JwksEndpoint&nbsp;(Uri&nbsp;jwks) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;result&nbsp;=&nbsp;Ok&nbsp;issuer &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;Fusebit.issuerExists&nbsp;result &nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;<span style="color:blue;">true</span>&nbsp;=!&nbsp;actual</pre> </p> <p> All tests here are structured according to the <a href="/2013/06/24/a-heuristic-for-formatting-code-according-to-the-aaa-pattern">AAA formatting heuristic</a>. This particular test may seem so obvious that you may wonder how there's actually any logic to test. Perhaps the next test throws a little more light on that question: </p> <p> <pre>[&lt;Fact&gt;] <span style="color:blue;">let</span>&nbsp;``Issuer&nbsp;doesn&#39;t&nbsp;exist``&nbsp;()&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">use</span>&nbsp;resp&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;HttpResponseMessage&nbsp;(HttpStatusCode.NotFound) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;result&nbsp;=&nbsp;Error&nbsp;resp &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;Fusebit.issuerExists&nbsp;result &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;<span style="color:blue;">false</span>&nbsp;=!&nbsp;actual</pre> </p> <p> How do we know that the requested issuer doesn't exist? It's not just any <code>Error</code> result that indicates that, but a particular <code>404 Not Found</code> result. Notice that this particular <code>Error</code> result translates to an <code>Ok</code> result: <code>Ok false</code>. </p> <p> All other kinds of <code>Error</code> results, on the other hand, should remain <code>Error</code> values: </p> <p> <pre>[&lt;Theory&gt;] [&lt;InlineData&nbsp;(HttpStatusCode.BadRequest)&gt;] [&lt;InlineData&nbsp;(HttpStatusCode.Unauthorized)&gt;] [&lt;InlineData&nbsp;(HttpStatusCode.Forbidden)&gt;] [&lt;InlineData&nbsp;(HttpStatusCode.InternalServerError)&gt;] <span style="color:blue;">let</span>&nbsp;``Issuer&nbsp;error``&nbsp;statusCode&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">use</span>&nbsp;resp&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;HttpResponseMessage&nbsp;(statusCode) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;expected&nbsp;=&nbsp;Error&nbsp;resp &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;Fusebit.issuerExists&nbsp;expected &nbsp;&nbsp;&nbsp;&nbsp;expected&nbsp;=!&nbsp;actual</pre> </p> <p> All together, these tests indicate an implementation like this: </p> <p> <pre><span style="color:green;">//&nbsp;Result&lt;&#39;a,&nbsp;HttpResponseMessage&gt;&nbsp;-&gt;&nbsp;Result&lt;bool,&nbsp;HttpResponseMessage&gt;</span> <span style="color:blue;">let</span>&nbsp;issuerExists&nbsp;=&nbsp;<span style="color:blue;">function</span> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Ok&nbsp;_&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;Ok&nbsp;<span style="color:blue;">true</span> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Error&nbsp;(resp&nbsp;:&nbsp;HttpResponseMessage)&nbsp;<span style="color:blue;">-&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;resp.StatusCode&nbsp;=&nbsp;HttpStatusCode.NotFound &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">then</span>&nbsp;Ok&nbsp;<span style="color:blue;">false</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">else</span>&nbsp;Error&nbsp;resp</pre> </p> <p> Once again, I've managed to write a function more generic than its name implies. This seems to happen to me a lot. </p> <p> In this context, what matters more is that this is another <a href="https://en.wikipedia.org/wiki/Pure_function">pure function</a> - which also explains why it was so easy to unit test. </p> <h3 id="ea0ca01fa88143e3adb23c5d883b6125"> Composition <a href="#ea0ca01fa88143e3adb23c5d883b6125" title="permalink">#</a> </h3> <p> It turned out that I'd now managed to extract all complexity to pure, testable functions. What remained was composing them together. </p> <p> First, a couple of private helper functions: </p> <p> <pre><span style="color:green;">//&nbsp;Task&lt;Result&lt;&#39;a,&nbsp;&#39;b&gt;&gt;&nbsp;-&gt;&nbsp;Task&lt;Result&lt;unit,&nbsp;&#39;b&gt;&gt;</span> <span style="color:blue;">let</span>&nbsp;ignoreOk&nbsp;x&nbsp;=&nbsp;TaskResult.map&nbsp;(<span style="color:blue;">fun</span>&nbsp;_&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;())&nbsp;x <span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;Task&lt;Result&lt;&#39;b,&nbsp;&#39;c&gt;&gt;)&nbsp;-&gt;&nbsp;Idempotent&lt;&#39;a&gt;&nbsp;-&gt;&nbsp;Task&lt;Result&lt;unit,&nbsp;&#39;c&gt;&gt;</span> <span style="color:blue;">let</span>&nbsp;whenMissing&nbsp;f&nbsp;=&nbsp;Idempotent.fold&nbsp;(f&nbsp;&gt;&gt;&nbsp;ignoreOk)&nbsp;(task&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;Ok&nbsp;()&nbsp;})</pre> </p> <p> These only exist to make the ensuing composition more readable. Since they both have a cyclomatic complexity of <em>1</em>, I found that <a href="/2018/11/12/what-to-test-and-not-to-test">it was okay to skip unit testing</a>. </p> <p> The same is true for the final composition: </p> <p> <pre><span style="color:blue;">let!</span>&nbsp;comp&nbsp;=&nbsp;taskResult&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;(issuer,&nbsp;identity,&nbsp;user)&nbsp;=&nbsp;gatherData&nbsp;dto &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;issuerExists&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Issuer.get&nbsp;client&nbsp;issuer.Id&nbsp;|&gt;&nbsp;Task.map&nbsp;Fusebit.issuerExists &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;userExists&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User.find&nbsp;client&nbsp;(IdentityCriterion&nbsp;identity) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;TaskResult.map&nbsp;(not&nbsp;&lt;&lt;&nbsp;List.isEmpty) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">do!</span>&nbsp;Idempotent.establish&nbsp;issuer&nbsp;issuerExists &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;whenMissing&nbsp;(Issuer.create&nbsp;client) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">do!</span>&nbsp;Idempotent.establish&nbsp;user&nbsp;userExists &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;whenMissing&nbsp;(User.create&nbsp;client)&nbsp;}</pre> </p> <p> The <code>comp</code> composition starts by gathering data from an incoming <code>dto</code> value. This code snippet is part of a slightly larger Controller Action that I'm not showing here. The rest of the surrounding method is irrelevant to the present example, since it only deals with translation of the input <a href="https://en.wikipedia.org/wiki/Data_transfer_object">Data Transfer Object</a> and from <code>comp</code> back to an <code>IHttpActionResult</code> object. </p> <p> After a little pure hors d'œuvre the sandwich arrives with the first impure actions: Retrieving the <code>issuerExists</code> and <code>userExists</code> values from the Fusebit API. After that, the sandwich does fall apart a bit, I admit. Perhaps it's more like a piece of <a href="https://en.wikipedia.org/wiki/Sm%C3%B8rrebr%C3%B8d">smørrebrød</a>... </p> <p> I could have written this composition with a more explicit sandwich structure, starting by exclusively calling <code>Issuer.get</code> and <code>User.find</code>. That would have been the first impure layer of the sandwich. </p> <p> As the pure centre, I could then have composed a pure function from <code>Fusebit.issuerExists</code>, <code>not &lt;&lt; List.isEmpty</code> and <code>Idempotent.establish</code>. </p> <p> Finally, I could have completed the sandwich with the second impure layer that'd call <code>whenMissing</code>. </p> <p> I admit that I didn't actually structure the code exactly like that. I mixed some of the pure functions (<code>Fusebit.issuerExists</code> and <code>not &lt;&lt; List.isEmpty</code>) with the initial queries by adding them as continuations with <code>Task.map</code> and <code>TaskResult.map</code>. Likewise, I decided to immediately pipe the results of <code>Idempotent.establish</code> to <code>whenMissing</code>. My motivation was that this made the code more readable, since I wanted to highlight the symmetry of the two actions. That mattered more to me, as a writer, than highlighting any sandwich structure. </p> <p> I'm not insisting I was right in making that choice. Perhaps I was; perhaps not. I'm only reporting what motivated me. </p> <p> Could the code be further improved? I wouldn't be surprised, but at this time I felt that it was good enough to submit to a code review, which it survived. </p> <p> One possible improvement, however, might be to parallelise the two actions, so that they could execute concurrently. I'm not sure it's worth the (small?) effort, though. </p> <h3 id="328d685313fd4141b3c9ea8f03e4c944"> Conclusion <a href="#328d685313fd4141b3c9ea8f03e4c944" title="permalink">#</a> </h3> <p> I'm always keen on examples that challenge the notion of the impureim sandwich architecture. Usually, I find that by taking a slightly more holistic view of what has to happen, I can make most problems fit the pattern. </p> <p> The most common counterargument is that subsequent impure queries may depend on decisions taken earlier. Thus, the argument goes, you can't gather all impure data up front. </p> <p> I'm sure that such situations genuinely exist, but I also think that they are rarer than most people think. In most cases I've experienced, even when I initially think that I've encountered such a situation, after a bit of reflection I find that I can structure the code to fit the <em>functional core, imperative shell</em> architecture. Not only that, but the code becomes simpler in the process. </p> <p> This happened in the example I've covered in this article. Initially, I though that ensuring that a Fusebit user exists would involve a process as illustrated in the first of the above flowcharts. Then, after thinking it over, I realised that defining a simple discriminated union would simplify matters <em>and</em> make the code testable. </p> <p> I thought it was worthwhile sharing that journey of discovery with others. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Nested type-safe DI Containers https://blog.ploeh.dk/2022/02/07/nested-type-safe-di-containers 2022-02-07T07:01:00+00:00 Mark Seemann <div id="post"> <p> <em>How to address the arity problem with type-safe DI Container prototypes.</em> </p> <p> This article is part of a series called <a href="/2022/01/10/type-safe-di-composition">Type-safe DI composition</a>. In the previous article, you saw <a href="/2022/01/31/a-type-safe-di-container-c-example">a C# example of a type-safe DI Container</a>. In case it's not clear from the article that introduces the series, there's really no point to any of this. My motivation for writing the article is that readers sometimes ask me about topics such as DI Containers versus type safety, or DI Containers in functional programming. The goal of these articles is to make it painfully clear why I find such ideas moot. </p> <h3 id="c261b81e550743df99709ff721e08807"> N+1 arity <a href="#c261b81e550743df99709ff721e08807" title="permalink">#</a> </h3> <p> The <a href="/2022/01/31/a-type-safe-di-container-c-example">previous article</a> suggested a series of generic containers in order to support type-safe Dependency Injection (DI) composition. For example, to support five services, you need five generic containers: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span> <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>&gt; <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>&gt; <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>,&nbsp;<span style="color:#2b91af;">T3</span>&gt; <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>,&nbsp;<span style="color:#2b91af;">T3</span>,&nbsp;<span style="color:#2b91af;">T4</span>&gt; <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>,&nbsp;<span style="color:#2b91af;">T3</span>,&nbsp;<span style="color:#2b91af;">T4</span>,&nbsp;<span style="color:#2b91af;">T5</span>&gt; </pre> </p> <p> As the above listing suggests, there's also an (effectively redundant) empty, non-generic <code>Container</code> class. Thus, in order to support five services, you need 5 + 1 = 6 <code>Container</code> classes. In order to support ten services, you'll need eleven classes, and so on. </p> <p> While these classes are all boilerplate and completely generic, you may still consider this a design flaw. If so, there's a workaround. </p> <h3 id="3ece4148c1d2449896e2f3bad3eb31e4"> Nested containers <a href="#3ece4148c1d2449896e2f3bad3eb31e4" title="permalink">#</a> </h3> <p> The key to avoid the <em>n + 1</em> arity problem is to nest the containers. First, we can delete <code><span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>,&nbsp;<span style="color:#2b91af;">T3</span>&gt;</code>, <code><span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>,&nbsp;<span style="color:#2b91af;">T3</span>,&nbsp;<span style="color:#2b91af;">T4</span>&gt;</code>, and <code><span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>,&nbsp;<span style="color:#2b91af;">T3</span>,&nbsp;<span style="color:#2b91af;">T4</span>,&nbsp;<span style="color:#2b91af;">T5</span>&gt;</code>, while leaving <code><span style="color:#2b91af;">Container</span></code> and <code><span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>&gt;</code> alone. </p> <p> <code><span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>&gt;</code> needs a few changes to its <code>Register</code> methods. </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Container&lt;T1,&nbsp;Container&lt;T2,&nbsp;T3&gt;&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T3</span>&gt;(T3&nbsp;<span style="color:#1f377f;">item3</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Container&lt;T1,&nbsp;Container&lt;T2,&nbsp;T3&gt;&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item1, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Container&lt;T2,&nbsp;T3&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item2, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item3)); }</pre> </p> <p> Instead of returning a <code>Container&lt;T1,&nbsp;T2,&nbsp;T3&gt;</code>, this version of <code>Register</code> returns a <code>Container&lt;T1,&nbsp;Container&lt;T2,&nbsp;T3&gt;&gt;</code>. Notice how <code>Item2</code> is a new container. A <code>Container&lt;T2, T3&gt;</code> is nested inside an outer container whose <code>Item1</code> remains of the type <code>T1</code>, but whose <code>Item2</code> is of the type <code>Container&lt;T2, T3&gt;</code>. </p> <p> The other <code>Register</code> overload follows suit: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Container&lt;T1,&nbsp;Container&lt;T2,&nbsp;T3&gt;&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T3</span>&gt;(Func&lt;T1,&nbsp;T2,&nbsp;T3&gt;&nbsp;<span style="color:#1f377f;">create</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(create&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(create)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">item3</span>&nbsp;=&nbsp;create(Item1,&nbsp;Item2); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Register(item3); }</pre> </p> <p> The only change to this method, compared to the <a href="/2022/01/31/a-type-safe-di-container-c-example">previous article</a>, is to the return type. </p> <h3 id="45e07d03149b44e7aabf566aa14e49f4"> Usage <a href="#45e07d03149b44e7aabf566aa14e49f4" title="permalink">#</a> </h3> <p> Since the input parameter types didn't change, composition still looks much the same: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">container</span>&nbsp;=&nbsp;Container.Empty &nbsp;&nbsp;&nbsp;&nbsp;.Register(Configuration) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreateRestaurantDatabase) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreatePostOffice) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreateClock()) &nbsp;&nbsp;&nbsp;&nbsp;.Register((<span style="color:#1f377f;">conf</span>,&nbsp;<span style="color:#1f377f;">cont</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompositionRoot.CreateRepository(conf,&nbsp;cont.Item1.Item2)); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">compositionRoot</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompositionRoot(container); services.AddSingleton&lt;IControllerActivator&gt;(compositionRoot);</pre> </p> <p> Only the last <code>Register</code> call is different. Instead of a lambda expression taking <em>four</em> arguments (<code>(c, _, po, __)</code>), this one only takes two: <code>(conf, cont)</code>. <code>conf</code> is an <code>IConfiguration</code> object, while <code>cont</code> is a nested container of the type <code>Container&lt;Container&lt;IRestaurantDatabase,&nbsp;IPostOffice&gt;,&nbsp;IClock&gt;</code>. </p> <p> Recall that the <code>CreateRepository</code> method has this signature: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IReservationsRepository&nbsp;<span style="color:#74531f;">CreateRepository</span>( &nbsp;&nbsp;&nbsp;&nbsp;IConfiguration&nbsp;<span style="color:#1f377f;">configuration</span>, &nbsp;&nbsp;&nbsp;&nbsp;IPostOffice&nbsp;<span style="color:#1f377f;">postOffice</span>)</pre> </p> <p> In order to produce the required <code>IPostOffice</code> object, the lambda expression must first read <code>Item1</code>, which has the type <code>Container&lt;IRestaurantDatabase,&nbsp;IPostOffice&gt;</code>. It can then read <em>that</em> container's <code>Item2</code> to get the <code>IPostOffice</code>. </p> <p> Not particularly readable, but type-safe. </p> <p> The entire <code>container</code> object passed into <code>CompositionRoot</code> has the type <code>Container&lt;IConfiguration,&nbsp;Container&lt;Container&lt;Container&lt;IRestaurantDatabase,&nbsp;IPostOffice&gt;,&nbsp;IClock&gt;,&nbsp;IReservationsRepository&gt;&gt;</code>. </p> <p> Equivalently, the <code>CompositionRoot</code>'s <code>Create</code> method has to <a href="https://en.wikipedia.org/wiki/Law_of_Demeter">train-wreck</a> its way to each service: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">object</span>&nbsp;<span style="color:#74531f;">Create</span>(ControllerContext&nbsp;<span style="color:#1f377f;">context</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(context&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(context)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;context.ActionDescriptor.ControllerTypeInfo; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(CalendarController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;CalendarController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2.Item1.Item1.Item1, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2.Item2); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(HomeController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;HomeController(container.Item2.Item1.Item1.Item1); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ReservationsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationsController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2.Item1.Item2, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2.Item1.Item1.Item1, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2.Item2); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(RestaurantsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;RestaurantsController(container.Item2.Item1.Item1.Item1); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ScheduleController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ScheduleController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2.Item1.Item1.Item1, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2.Item2, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AccessControlList.FromUser(context.HttpContext.User)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;Unexpected&nbsp;controller&nbsp;type:&nbsp;</span>{t}<span style="color:#a31515;">.&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(context)); }</pre> </p> <p> Notice how most of the services depend on <code>container.Item2.Item1.Item1.Item1</code>. If you hover over that code in an <a href="https://en.wikipedia.org/wiki/Integrated_development_environment">IDE</a>, you'll see that this is an <code>IRestaurantDatabase</code> service. Again, type-safe, but hardly readable. </p> <h3 id="d311f951726146d39bc7402d756b8032"> Conclusion <a href="#d311f951726146d39bc7402d756b8032" title="permalink">#</a> </h3> <p> You can address the <em>n + 1 arity</em> problem by nesting generic containers inside each other. How did I think of this solution? And can we simplify things even more? </p> <p> Read on. </p> <p> <strong>Next:</strong> <a href="/2022/02/21/a-type-safe-di-container-as-a-functor">A type-safe DI Container as a functor</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. A type-safe DI Container C# example https://blog.ploeh.dk/2022/01/31/a-type-safe-di-container-c-example 2022-01-31T06:42:00+00:00 Mark Seemann <div id="post"> <p> <em>An ultimately pointless exploration of options.</em> </p> <p> This article is part of a series called <a href="/2022/01/10/type-safe-di-composition">Type-safe DI composition</a>. In the previous article, you saw <a href="/2022/01/24/type-level-di-container-prototype">a type-level prototype</a> written in <a href="https://www.haskell.org">Haskell</a>. If you don't read Haskell code, then it's okay to skip that article and instead start reading here. I'm not going to assume that you've read and understood the previous article. </p> <p> In this article, I'll begin exploration of a type-safe Dependency Injection (DI) Container prototype written in C#. In order to demonstrate that it works in a realistic environment, I'm going to use it in the code base that accompanies <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. </p> <h3 id="1d6113f811d348f593851f8e54896105"> Empty container <a href="#1d6113f811d348f593851f8e54896105" title="permalink">#</a> </h3> <p> Like the previous article, we can start with an empty container: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Container&nbsp;Empty&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Container(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">Container</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Container&lt;T1&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T1</span>&gt;(T1&nbsp;<span style="color:#1f377f;">item1</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Container&lt;T1&gt;(item1); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The only API this class affords is the <code>Empty</code> <a href="https://en.wikipedia.org/wiki/Singleton_pattern">Singleton</a> instance and the <code>Register</code> method. As you can tell from the signature, this method returns a different container type. </p> <h3 id="a566b84277eb413ea29ce0ab9094ff51"> Generic container with one item <a href="#a566b84277eb413ea29ce0ab9094ff51" title="permalink">#</a> </h3> <p> The above <code>Register</code> method returns a <code>Container&lt;T1&gt;</code> instance. This class is defined like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Container</span>(T1&nbsp;<span style="color:#1f377f;">item1</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item1&nbsp;=&nbsp;item1; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T1&nbsp;Item1&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;More&nbsp;members&nbsp;here...</span></pre> </p> <p> This enables you to add a single service of any type <code>T1</code>. For example, if you <code>Register</code> an <code>IConfiguration</code> instance, you'll have a <code>Container&lt;IConfiguration&gt;</code>: </p> <p> <pre>Container&lt;IConfiguration&gt;&nbsp;<span style="color:#1f377f;">container</span>&nbsp;=&nbsp;Container.Empty.Register(Configuration);</pre> </p> <p> The static type system tells you that <code>Item1</code> contains an <code>IConfiguration</code> object - not a collection of <code>IConfiguration</code> objects, or one that may or may not be there. There's guaranteed to be one and only one. No <a href="/2013/07/08/defensive-coding">defensive coding</a> is required: </p> <p> <pre>IConfiguration&nbsp;<span style="color:#1f377f;">conf</span>&nbsp;=&nbsp;container.Item1;</pre> </p> <p> A container that contains only a single service is, however, hardly interesting. How do we add more services? </p> <h3 id="a43d9f12300d45c68b4b7fad248010a2"> Registration <a href="#a43d9f12300d45c68b4b7fad248010a2" title="permalink">#</a> </h3> <p> The <code>Container&lt;T1&gt;</code> class affords a <code>Register</code> method of its own: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Container&lt;T1,&nbsp;T2&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T2</span>&gt;(T2&nbsp;<span style="color:#1f377f;">item2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Container&lt;T1,&nbsp;T2&gt;(Item1,&nbsp;item2); }</pre> </p> <p> This method return a new container that contains both <code>Item1</code> and <code>item2</code>. </p> <p> There's also a convenient overload that, in some scenarios, better support method chaining: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Container&lt;T1,&nbsp;T2&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T2</span>&gt;(Func&lt;T1,&nbsp;T2&gt;&nbsp;<span style="color:#1f377f;">create</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(create&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(create)); &nbsp;&nbsp;&nbsp;&nbsp;T2&nbsp;<span style="color:#1f377f;">item2</span>&nbsp;=&nbsp;create(Item1); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Register(item2); }</pre> </p> <p> This method runs a <code>create</code> function to produce an object of the type <code>T2</code> given the already-registered service <code>Item1</code>. </p> <p> As an example, the code base's <a href="/2011/07/28/CompositionRoot">Composition Root</a> defines a method for creating an <code>IRestaurantDatabase</code> object: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IRestaurantDatabase&nbsp;<span style="color:#74531f;">CreateRestaurantDatabase</span>( &nbsp;&nbsp;&nbsp;IConfiguration&nbsp;<span style="color:#1f377f;">configuration</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(configuration&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(configuration)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">restaurantsOptions</span>&nbsp;=&nbsp;configuration.GetSection(<span style="color:#a31515;">&quot;Restaurants&quot;</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Get&lt;RestaurantOptions[]&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;InMemoryRestaurantDatabase(restaurantsOptions &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Select(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;r.ToRestaurant()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.OfType&lt;Restaurant&gt;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ToArray()); }</pre> </p> <p> Notice that this method takes an <code>IConfiguration</code> object as input. You can now use the <code>Register</code> overload to add the <code>IRestaurantDatabase</code> service to the container: </p> <p> <pre>Container&lt;IConfiguration,&nbsp;IRestaurantDatabase&gt;&nbsp;<span style="color:#1f377f;">container</span>&nbsp;=&nbsp;Container.Empty &nbsp;&nbsp;&nbsp;&nbsp;.Register(Configuration) &nbsp;&nbsp;&nbsp;&nbsp;.Register(<span style="color:#1f377f;">conf</span>&nbsp;=&gt;&nbsp;CompositionRoot.CreateRestaurantDatabase(conf));</pre> </p> <p> Or, via eta reduction: </p> <p> <pre>Container&lt;IConfiguration,&nbsp;IRestaurantDatabase&gt;&nbsp;<span style="color:#1f377f;">container</span>&nbsp;=&nbsp;Container.Empty &nbsp;&nbsp;&nbsp;&nbsp;.Register(Configuration) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreateRestaurantDatabase);</pre> </p> <p> You've probably noticed that this container is one with <em>two</em> generic type arguments. </p> <h3 id="4cc0437bb0e14543a63d650df7f07e32"> Generic container with two items <a href="#4cc0437bb0e14543a63d650df7f07e32" title="permalink">#</a> </h3> <p> This new class is, not surprisingly, defined like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Container</span>&lt;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Container</span>(T1&nbsp;<span style="color:#1f377f;">item1</span>,&nbsp;T2&nbsp;<span style="color:#1f377f;">item2</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item1&nbsp;=&nbsp;item1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item2&nbsp;=&nbsp;item2; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T1&nbsp;Item1&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T2&nbsp;Item2&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Container&lt;T1,&nbsp;T2,&nbsp;T3&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T3</span>&gt;(T3&nbsp;<span style="color:#1f377f;">item3</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Container&lt;T1,&nbsp;T2,&nbsp;T3&gt;(Item1,&nbsp;Item2,&nbsp;item3); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Container&lt;T1,&nbsp;T2,&nbsp;T3&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T3</span>&gt;(Func&lt;T1,&nbsp;T2,&nbsp;T3&gt;&nbsp;<span style="color:#1f377f;">create</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(create&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(create)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">item3</span>&nbsp;=&nbsp;create(Item1,&nbsp;Item2); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Register(item3); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>?&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;Container&lt;T1,&nbsp;T2&gt;&nbsp;<span style="color:#1f377f;">container</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;T1&gt;.Default.Equals(Item1,&nbsp;container.Item1)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;T2&gt;.Default.Equals(Item2,&nbsp;container.Item2); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;HashCode.Combine(Item1,&nbsp;Item2); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Like <code>Container&lt;T1&gt;</code> it also defines two <code>Register</code> overloads that enable you to add yet another service. </p> <p> If you're on C# 9 or later, you could dispense with much of the boilerplate code by defining the type as a <code>record</code> instead of a <code>class</code>. </p> <h3 id="b2771d4cd9a04cf7932195fe9a8b478c"> Containers of higher arity <a href="#b2771d4cd9a04cf7932195fe9a8b478c" title="permalink">#</a> </h3> <p> You've probably noticed a pattern. Each <code>Register</code> method just returns a container with incremented arity: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Container&lt;T1,&nbsp;T2,&nbsp;T3,&nbsp;T4&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T4</span>&gt;(T4&nbsp;<span style="color:#1f377f;">item4</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Container&lt;T1,&nbsp;T2,&nbsp;T3,&nbsp;T4&gt;(Item1,&nbsp;Item2,&nbsp;Item3,&nbsp;item4); }</pre> </p> <p> and </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Container&lt;T1,&nbsp;T2,&nbsp;T3,&nbsp;T4,&nbsp;T5&gt;&nbsp;<span style="color:#74531f;">Register</span>&lt;<span style="color:#2b91af;">T5</span>&gt;(T5&nbsp;<span style="color:#1f377f;">item5</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Container&lt;T1,&nbsp;T2,&nbsp;T3,&nbsp;T4,&nbsp;T5&gt;(Item1,&nbsp;Item2,&nbsp;Item3,&nbsp;Item4,&nbsp;item5); }</pre> </p> <p> and so on. </p> <p> Wait! Does every new service require a new class? What if you have 143 services to <a href="/2010/09/29/TheRegisterResolveReleasepattern">register</a>? </p> <p> Well, yes, as presented here, you'll need 144 classes (one for each service, plus the empty container). They'd all be generic, so you could imagine making a reusable library that defines all these classes. It is, however, pointless for several reasons: <ul> <li>You shouldn't have that many services. Do yourself a favour and <a href="https://stackoverflow.blog/2022/01/03/favor-real-dependencies-for-unit-testing/">have a service for each 'real' architectural dependency</a>: 1. Database, 2. Email gateway, 3. Third-party HTTP service, etc. Also, add a service for anything else that's not <a href="https://en.wikipedia.org/wiki/Referential_transparency">referentially transparent</a>, such as clocks and random number generators. For the example restaurant reservation system, the greatest arity I needed was 5: <code>Container&lt;T1, T2, T3, T4, T5&gt;</code>.</li> <li>You don't need a container for each arity after all, as the next article will demonstrate.</li> <li>This is all pointless anyway, as already predicted in the <a href="/2022/01/10/type-safe-di-composition">introduction article</a>.</li> </ul> For now, then, I'll continue with the example. There are five generic container classes, as well as the empty one (which really is redundant, but so is all of this). </p> <h3 id="0323fc5a24fc4397b67203f4c71e64cf"> Usage <a href="#0323fc5a24fc4397b67203f4c71e64cf" title="permalink">#</a> </h3> <p> You can create a statically typed container by registering all the required services: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">container</span>&nbsp;=&nbsp;Container.Empty &nbsp;&nbsp;&nbsp;&nbsp;.Register(Configuration) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreateRestaurantDatabase) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreatePostOffice) &nbsp;&nbsp;&nbsp;&nbsp;.Register(CompositionRoot.CreateClock()) &nbsp;&nbsp;&nbsp;&nbsp;.Register( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:#1f377f;">c</span>,&nbsp;<span style="color:#1f377f;">_</span>,&nbsp;<span style="color:#1f377f;">po</span>,&nbsp;<span style="color:#1f377f;">__</span>)&nbsp;=&gt;&nbsp;CompositionRoot.CreateRepository(c,&nbsp;po));</pre> </p> <p> The <code>container</code> object has the type <code>Container&lt;IConfiguration,&nbsp;IRestaurantDatabase,&nbsp;IPostOffice,&nbsp;IClock,&nbsp;IReservationsRepository&gt; </code>, which is quite a mouthful. You can, however, pass it to the <code>CompositionRoot</code> and register it as the application's <code>IControllerActivator</code>: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">compositionRoot</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompositionRoot(container); services.AddSingleton&lt;IControllerActivator&gt;(compositionRoot);</pre> </p> <p> <code>CompositionRoot.Create</code> uses the injected <code>container</code> to create Controllers: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">object</span>&nbsp;<span style="color:#74531f;">Create</span>(ControllerContext&nbsp;<span style="color:#1f377f;">context</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(context&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(context)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;context.ActionDescriptor.ControllerTypeInfo; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(CalendarController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;CalendarController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item5); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(HomeController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;HomeController(container.Item2); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ReservationsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationsController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item4, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item5); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(RestaurantsController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;RestaurantsController(container.Item2); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(t&nbsp;==&nbsp;<span style="color:blue;">typeof</span>(ScheduleController)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ScheduleController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item2, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.Item5, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AccessControlList.FromUser(context.HttpContext.User)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;Unexpected&nbsp;controller&nbsp;type:&nbsp;</span>{t}<span style="color:#a31515;">.&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(context)); }</pre> </p> <p> Having to refer to <code>Item2</code>, <code>Item5</code>, etc. instead of named services leaves better readability to be desired, but <a href="https://amzn.to/2PzDpJu">in the end, it doesn't even matter</a>, because, as you'll see as this article series progresses, this is all moot. </p> <h3 id="230326b6b3f147709ade44982feffbb5"> Conclusion <a href="#230326b6b3f147709ade44982feffbb5" title="permalink">#</a> </h3> <p> You can define a type-safe DI Container with a series of generic containers. Each registered service has a generic type, so if you need a single <code>IFoo</code>, you register a single <code>IFoo</code> object. If you need a collection of <code>IBar</code> objects, you register an <code>IReadOnlyCollection&lt;IBar&gt;</code>, and so on. This means that you don't have to waste brain capacity remembering the configuration of all services. </p> <p> Compared to the initial Haskell prototype, the C# example shown here doesn't prevent you from registering the same type more than once. I don't know of a way to do this at the type level in C#, and while you could make a run-time check to prevent this, I didn't implement it. After all, as this article series will demonstrate, none of this is particularly useful, because <a href="/2014/06/10/pure-di">Pure Di</a> is simpler without being less powerful. </p> <p> If you were concerned about the proliferation of generic classes with increasing type argument arity, then rest assured that this isn't a problem. The next article in the series will demonstrate how to get around that issue. </p> <p> <strong>Next:</strong> <a href="/2022/02/07/nested-type-safe-di-containers">Nested type-safe DI Containers</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Type-level DI Container prototype https://blog.ploeh.dk/2022/01/24/type-level-di-container-prototype 2022-01-24T06:48:00+00:00 Mark Seemann <div id="post"> <p> <em>A fairly pointless Haskell exercise.</em> </p> <p> This article is part of a series called <a href="/2022/01/10/type-safe-di-composition">Type-safe DI composition</a>. </p> <p> People sometimes ask me how to do Dependency Injection (DI) in Functional Programming, and the short answer is that <a href="/2017/02/02/dependency-rejection">you don't</a>. DI makes everything impure, while the entire <a href="/2018/11/19/functional-architecture-a-definition">point of FP is to write as much referentially transparent code as possible</a>. Instead, you should aim for the <a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">Functional Core, Imperative Shell</a> style of architecture (AKA <a href="/2020/03/02/impureim-sandwich">impureim sandwich</a>). </p> <p> Occasionally, someone might point out that you can use the <a href="/2021/10/04/reader-as-a-contravariant-functor">contravariant Reader functor</a> with a 'registry' of services to <a href="/2022/03/21/contravariant-dependency-injection">emulate a DI Container in FP</a>. </p> <p> Not really, because even if you make the dependencies implicitly available as the Reader 'environment', they're still impure. More on that in a future article, though. </p> <p> Still, what's a DI Container but <a href="https://ayende.com/blog/2886/building-an-ioc-container-in-15-lines-of-code">a dictionary of objects, keyed by type</a>? After I read <a href="https://thinkingwithtypes.com/">Thinking with Types</a> I thought I'd do the exercise and write a type-level container of values in Haskell. </p> <h3 id="e60305d1f0914fd689209c6aa2da5f1e"> Module <a href="#e60305d1f0914fd689209c6aa2da5f1e" title="permalink">#</a> </h3> <p> The <code>TLContainer</code> module requires a smorgasbord of extensions and a few imports: </p> <p> <pre>{-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;AllowAmbiguousTypes&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;ConstraintKinds&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;DataKinds&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;PolyKinds&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;GADTs&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;ScopedTypeVariables&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;TypeApplications&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;TypeOperators&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;TypeFamilies&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;FlexibleContexts&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;RankNTypes&nbsp;#-} {-#&nbsp;<span style="color:gray;">LANGUAGE</span>&nbsp;UndecidableInstances&nbsp;#-} <span style="color:blue;">module</span>&nbsp;TLContainer&nbsp;(<span style="color:blue;">Container</span>&nbsp;(),&nbsp;<span style="color:#2b91af;">nil</span>,&nbsp;<span style="color:#2b91af;">insert</span>,&nbsp;<span style="color:#2b91af;">get</span>)&nbsp;<span style="color:blue;">where</span> <span style="color:blue;">import</span>&nbsp;Data.Kind <span style="color:blue;">import</span>&nbsp;Data.Proxy <span style="color:blue;">import</span>&nbsp;GHC.TypeLits <span style="color:blue;">import</span>&nbsp;Fcf <span style="color:blue;">import</span>&nbsp;Unsafe.Coerce&nbsp;(<span style="color:#2b91af;">unsafeCoerce</span>) </pre> </p> <p> Notice that the module only exports the <code>Container</code> type, but not its data constructor. You'll have to use <code>nil</code> and <code>insert</code> to create values of the type. </p> <h3 id="ff97b224b8e04299a8ee100fbc944adf"> Data types <a href="#ff97b224b8e04299a8ee100fbc944adf" title="permalink">#</a> </h3> <p> The <code>Container</code> should be able to store an arbitrary number of services of arbitrary types. This doesn't sound like a good fit for a statically typed language like Haskell, but it's possible to do this with existential types. Define an existential type that models a container registration: </p> <p> <pre><span style="color:blue;">data</span>&nbsp;Reg&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;Reg&nbsp;::&nbsp;a&nbsp;-&gt;&nbsp;Reg </pre> </p> <p> The problem with existential types is that the type argument <code>a</code> is lost at compile time. If you have a <code>Reg</code> value, it contains a value (e.g. a service) of a particular type, but you don't know what it is. </p> <p> You can solve this by keeping track of the types at the type level of the container itself. The <code>Container</code> data type is basically just a wrapper around a list of <code>Reg</code> values: </p> <p> <pre><span style="color:blue;">data</span>&nbsp;Container&nbsp;(ts&nbsp;::&nbsp;[k])&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;UnsafeContainer&nbsp;::&nbsp;[Reg]&nbsp;-&gt;&nbsp;Container&nbsp;ts </pre> </p> <p> The name of the data constructor is <code>UnsafeContainer</code> because it's unsafe. It would enable you to add multiple registrations of the same type. The container shouldn't allow that, so the module doesn't export <code>UnsafeContainer</code>. Instead, it defines sufficient type-level constraints to guarantee that if you try to add two registrations of the same type, your code isn't going to compile. </p> <p> This is the principal feature that distinguishes <code>Container</code> from the set of tuples that Haskell already defines. </p> <h3 id="9299405418b44b7dbe35310f11543e7a"> Registration <a href="#9299405418b44b7dbe35310f11543e7a" title="permalink">#</a> </h3> <p> The module exports an empty <code>Container</code>: </p> <p> <pre><span style="color:#2b91af;">nil</span>&nbsp;::&nbsp;<span style="color:blue;">Container</span>&nbsp;&#39;[] nil&nbsp;=&nbsp;UnsafeContainer&nbsp;<span style="color:blue;">[]</span> </pre> </p> <p> Not only is this container empty, it's also statically typed that way. The type <code>Container '[]</code> is isomorphic to <code>()</code>. </p> <p> The <code>nil</code> container gives you a container so that you can get started. You can add a registration to <code>nil</code>, and that's going to return a new container. You can add another registration to that container, and so on. </p> <p> The distinguishing feature of <code>Container</code>, however, is that you can only add one registration of a given type. If you want to register multiple services of the same type, register a list of them. </p> <p> Code like <code>insert readReservations $ insert readReservations nil</code> shouldn't compile, because it tries to <code>insert</code> the same service (<code>readReservations</code>) twice. To enable that feature, the module must be able to detect type uniqueness at the type level. This is possible with the help from <a href="https://hackage.haskell.org/package/first-class-families">the first-class-families package</a>: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;UniqueType&nbsp;(t&nbsp;::&nbsp;k)&nbsp;(ts&nbsp;::&nbsp;[k])&nbsp;=&nbsp;Null&nbsp;=&lt;&lt;&nbsp;Filter&nbsp;(TyEq&nbsp;t)&nbsp;ts </pre> </p> <p> This type models the condition that the type <code>t</code> must not be in the list of types <code>ts</code>. It almost looks like regular Haskell code at the term level, but it works at the type level. <code>Null</code> is a type that can be evaluated to Boolean types at compile-time, depending on whether a list is empty or not. </p> <p> This enables you to define a closed type family that will produce a compile-time error if a candidate type isn't unique: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;family&nbsp;RequireUniqueType&nbsp;(result&nbsp;::&nbsp;Bool)&nbsp;(t&nbsp;::&nbsp;k)&nbsp;::&nbsp;Constraint&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;RequireUniqueType&nbsp;&nbsp;&#39;True&nbsp;t&nbsp;=&nbsp;<span style="color:blue;">()</span> &nbsp;&nbsp;RequireUniqueType&nbsp;&#39;False&nbsp;t&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;TypeError&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;Text&nbsp;<span style="color:#a31515;">&quot;Attempting&nbsp;to&nbsp;add&nbsp;the&nbsp;type&nbsp;&quot;</span>&nbsp;&#39;:&lt;&gt;: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;ShowType&nbsp;t&nbsp;&#39;:&lt;&gt;: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;Text&nbsp;<span style="color:#a31515;">&quot;&nbsp;to&nbsp;the&nbsp;container,&nbsp;but&nbsp;this&nbsp;container&nbsp;already&nbsp;contains&nbsp;that&nbsp;type.&quot;</span>) </pre> </p> <p> Combined with the <code>UniqueType</code> alias, you can now define the <code>insert</code> function: </p> <p> <pre><span style="color:#2b91af;">insert</span>&nbsp;::&nbsp;<span style="color:blue;">RequireUniqueType</span>&nbsp;(<span style="color:blue;">Eval</span>&nbsp;(<span style="color:blue;">UniqueType</span>&nbsp;t&nbsp;ts))&nbsp;t &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;t&nbsp;-&gt;&nbsp;Container&nbsp;ts&nbsp;-&gt;&nbsp;Container&nbsp;(t&nbsp;&#39;:&nbsp;ts) insert&nbsp;x&nbsp;(UnsafeContainer&nbsp;xs)&nbsp;=&nbsp;UnsafeContainer&nbsp;(Reg&nbsp;x&nbsp;:&nbsp;xs) </pre> </p> <p> This function enables you to register multiple services, like this: </p> <p> <pre><span style="color:#2b91af;">container</span>&nbsp;::&nbsp;<span style="color:blue;">Container</span>&nbsp;&#39;[<span style="color:blue;">LocalTime</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">IO</span>&nbsp;[<span style="color:blue;">Reservation</span>],&nbsp;<span style="color:blue;">Reservation</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">IO</span>&nbsp;()] container&nbsp;=&nbsp;insert&nbsp;readReservations&nbsp;$&nbsp;insert&nbsp;createReservation&nbsp;nil</pre> </p> <p> If, on the other hand, you attempt to register the same service multiple times, your code doesn't compile. You might, for example, attempt to do something like this: </p> <p> <pre>container&#39;&nbsp;=&nbsp;insert&nbsp;readReservations&nbsp;container</pre> </p> <p> When you try to compile your code, however, it doesn't: </p> <p> <pre> * Attempting to add the type LocalTime -> IO [Reservation] to the container, but this container already contains that type. * In the expression: insert readReservations container In an equation for container': container' = insert readReservations container <span style="color: blue">|</span> <span style="color: blue">36 |</span> container' = <span style="color: red">insert readReservations container</span> <span style="color: blue">|</span> <span style="color: red">^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^</span></pre> </p> <p> As a proof of concept, that's good enough for me. A type-safe set of uniquely typed registrations. </p> <h3 id="fb31959c8c8545879c5266466de2ce1e"> Retrieval <a href="#fb31959c8c8545879c5266466de2ce1e" title="permalink">#</a> </h3> <p> Given that <code>Container</code> is a wrapper over a list of existential types, it seems as though the type information is lost. It isn't, though. Consider the type of the above <code>container</code> value. At the type level, you can see that it contains two services: one with the type <code>LocalTime -&gt; IO [Reservation]</code>, and another with the type <code>Reservation -&gt; IO ()</code>. Not only that, but the compiler can see the position of each of those types. Due to the way <code>insert</code> is implemented, that order corresponds to the order of <code>Reg</code> values. </p> <p> First, define a type alias to find the index of a type <code>t</code> in a list of types <code>ts</code>: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;FindElem&nbsp;(t&nbsp;::&nbsp;k)&nbsp;(ts&nbsp;::&nbsp;[k])&nbsp;= &nbsp;&nbsp;FromMaybe&nbsp;Stuck&nbsp;=&lt;&lt;&nbsp;FindIndex&nbsp;(TyEq&nbsp;t)&nbsp;ts </pre> </p> <p> This is again the <em>first-class-families</em> package in action. <code>FindIndex</code> finds a <code>Nat</code> that represents the index if the type is there. If it isn't there, the type is equivalent to <code>Stuck</code>, which is the type-level equivalent of <code>undefined</code>. <code>Nat</code> is a <code>KnownNat</code> instance, whereas <code>Stuck</code> isn't, which now enables you to define a constraint: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;IsMember&nbsp;t&nbsp;ts&nbsp;=&nbsp;KnownNat&nbsp;(Eval&nbsp;(FindElem&nbsp;t&nbsp;ts))</pre> </p> <p> The <code>IsMember</code> constraint limits <code>t</code> to belong to <code>ts</code>. With it, you can now define a helper function to find the index of a type <code>t</code> in a list of types <code>ts</code>: </p> <p> <pre><span style="color:#2b91af;">findElem</span>&nbsp;::&nbsp;forall&nbsp;t&nbsp;ts.&nbsp;<span style="color:blue;">IsMember</span>&nbsp;t&nbsp;ts&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;<span style="color:#2b91af;">Int</span> findElem&nbsp;=&nbsp;<span style="color:blue;">fromIntegral</span>&nbsp;.&nbsp;natVal&nbsp;$&nbsp;Proxy&nbsp;@(Eval&nbsp;(FindElem&nbsp;t&nbsp;ts)) </pre> </p> <p> Because of the <code>IsMember</code> constraint, we know that <code>t</code> must be a member of <code>ts</code>. You can't call <code>findElem</code> if that's not the case; your code wouldn't compile. </p> <p> You can now define a function to retrieve a service from a <code>Container</code>: </p> <p> <pre><span style="color:#2b91af;">get</span>&nbsp;::&nbsp;forall&nbsp;t&nbsp;ts.&nbsp;<span style="color:blue;">IsMember</span>&nbsp;t&nbsp;ts&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;<span style="color:blue;">Container</span>&nbsp;ts&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;t get&nbsp;(UnsafeContainer&nbsp;xs)&nbsp;=&nbsp;unReg&nbsp;$&nbsp;xs&nbsp;!!&nbsp;findElem&nbsp;@t&nbsp;@ts &nbsp;&nbsp;<span style="color:blue;">where</span>&nbsp;unReg&nbsp;(Reg&nbsp;x)&nbsp;=&nbsp;unsafeCoerce&nbsp;x </pre> </p> <p> The <code>get</code> function first finds the index of the type <code>t</code> in <code>ts</code>. It then uses the (unsafe) list index operator <code>!!</code> to get the correct <code>Reg</code> value out of <code>x</code>. While the use of <code>!!</code> is generally considered unsafe (or, at least, partial) in Haskell, we <em>know</em> that the element is there because of the <code>IsMember</code> constraint. </p> <p> Furthermore, because of the way <code>insert</code> builds up the container, we know that the service inside the existential type <code>Reg</code> must be of the type <code>t</code>. Thus, it's safe to use <code>unsafeCoerce</code>. </p> <h3 id="243221d6a21442b78c2fe54c942d33e3"> Example <a href="#243221d6a21442b78c2fe54c942d33e3" title="permalink">#</a> </h3> <p> Imagine that you've created the above <code>container</code>. You can now retrieve services from it as necessary. </p> <p> For example, to implement a HTTP GET resource that returns a list of reservations for a given date, you could do something like this: </p> <p> <pre><span style="color:#2b91af;">getReservations</span>&nbsp;::&nbsp;<span style="color:blue;">LocalTime</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">IO</span>&nbsp;(<span style="color:blue;">HTTPResult</span>&nbsp;[<span style="color:blue;">Reservation</span>]) getReservations&nbsp;date&nbsp;=&nbsp;<span style="color:blue;">do</span> &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;svc&nbsp;=&nbsp;get&nbsp;container&nbsp;::&nbsp;LocalTime&nbsp;-&gt;&nbsp;IO&nbsp;[Reservation] &nbsp;&nbsp;reservations&nbsp;&lt;-&nbsp;svc&nbsp;date &nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;$&nbsp;OK&nbsp;reservations</pre> </p> <p> Nothing much happens here. You could imagine that proper input validation of <code>date</code> is done before the service is invoked, or that some mapping operation is done on <code>reservations</code> before the function returns them. I omitted those steps, since they're not what matters. What matters is that that you can use <code>get</code> to safely get a service of the type <code>LocalTime -&gt; IO [Reservation]</code>. </p> <p> Likewise, you could implement an HTTP POST resource that clients can use use to create new reservations: </p> <p> <pre><span style="color:#2b91af;">postReservation</span>&nbsp;::&nbsp;<span style="color:blue;">Reservation</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">IO</span>&nbsp;(<span style="color:blue;">HTTPResult</span>&nbsp;()) postReservation&nbsp;dto&nbsp;=&nbsp;<span style="color:blue;">do</span> &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;svc&nbsp;=&nbsp;get&nbsp;container&nbsp;::&nbsp;Reservation&nbsp;-&gt;&nbsp;IO&nbsp;<span style="color:blue;">()</span> &nbsp;&nbsp;svc&nbsp;dto &nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;$&nbsp;OK&nbsp;<span style="color:blue;">()</span></pre> </p> <p> Since the compiler knows that <code>container</code> also contains a service of the type <code>Reservation -&gt; IO ()</code>, this still compiles. </p> <p> If, on the other hand, you attempted to implement a single HTTP GET resource, the following wouldn't compile: </p> <p> <pre><span style="color:#2b91af;">getSingleReservation</span>&nbsp;::&nbsp;<span style="color:blue;">LocalTime</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">IO</span>&nbsp;(<span style="color:blue;">HTTPResult</span>&nbsp;<span style="color:blue;">Reservation</span>) getSingleReservation&nbsp;date&nbsp;email&nbsp;=&nbsp;<span style="color:blue;">do</span> &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;svc&nbsp;=&nbsp;get&nbsp;container&nbsp;::&nbsp;LocalTime&nbsp;-&gt;&nbsp;String&nbsp;-&gt;&nbsp;IO&nbsp;(Maybe&nbsp;Reservation) &nbsp;&nbsp;mres&nbsp;&lt;-&nbsp;svc&nbsp;date&nbsp;email &nbsp;&nbsp;<span style="color:blue;">case</span>&nbsp;mres&nbsp;<span style="color:blue;">of</span> &nbsp;&nbsp;&nbsp;&nbsp;Just&nbsp;r&nbsp;-&gt;&nbsp;<span style="color:blue;">return</span>&nbsp;$&nbsp;OK&nbsp;r &nbsp;&nbsp;&nbsp;&nbsp;Nothing&nbsp;-&gt;&nbsp;<span style="color:blue;">return</span>&nbsp;$&nbsp;NotFound</pre> </p> <p> The <code>get container</code> line doesn't compile because <code>container</code> doesn't contain a service of the type <code>LocalTime -&gt; String -&gt; IO (Maybe Reservation)</code>, and the compiler can tell. </p> <p> If you truly want to add that feature, you'll have to first register that service with the container: </p> <p> <pre><span style="color:#2b91af;">container</span>&nbsp;::&nbsp;<span style="color:blue;">Container</span>&nbsp;&#39;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LocalTime&nbsp;-&gt;&nbsp;String&nbsp;-&gt;&nbsp;IO&nbsp;(Maybe&nbsp;Reservation), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LocalTime&nbsp;-&gt;&nbsp;IO&nbsp;[Reservation], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;-&gt;&nbsp;IO&nbsp;<span style="color:blue;">()</span>] container&nbsp;= &nbsp;&nbsp;insert&nbsp;readReservation&nbsp;$ &nbsp;&nbsp;insert&nbsp;readReservations&nbsp;$ &nbsp;&nbsp;insert&nbsp;createReservation&nbsp;nil</pre> </p> <p> Notice that the type of <code>container</code> has now changed. It now contains three services instead of two. The <code>getSingleReservation</code> action now compiles. </p> <h3 id="25a8d28be45a4ef1a5eb9732427c7ef0"> Uniqueness <a href="#25a8d28be45a4ef1a5eb9732427c7ef0" title="permalink">#</a> </h3> <p> The <code>Container</code> shown here is essentially just a glorified tuple. The only distinguishing trait is that you can define a tuple where two or more elements have the same type, such as <code>(String, Bool, String)</code>, whereas this isn't possible with <code>Container</code>. You can define a <code>Container '[String, Bool]</code>, but not <code>Container '[String, Bool, String]</code>. </p> <p> Why is this desirable? </p> <p> This stems from <a href="https://twitter.com/bogdangaliceanu/status/1252151352119132160">a short and (friendly, I hope) Twitter discussion</a> initiated by <a href="https://twitter.com/bogdangaliceanu">Bogdan Galiceanu</a>. We were discussing whether it'd be more appropriate to use <a href="https://docs.microsoft.com/dotnet/api/system.linq.enumerable.singleordefault">SingleOrDefault</a> to manipulate a service in a DI Container, or <code>foreach</code>. </p> <blockquote> <p> "Yeah, I wasn't explicit and clarified in a second tweet. I didn't mean in the services example, but in general where it helps if the reader's mental model of the code has 1 item from the collection, because that's how it is in real life. SingleOrDefault would enforce this." </p> <footer><cite><a href="https://twitter.com/bogdangaliceanu/status/1252210213211582477">Bogdan Galiceanu</a></cite></footer> </blockquote> <p> The point being made here is that while you have a dictionary of <em>collections</em>, you expect certain (if not all) of these collections to be <a href="https://en.wikipedia.org/wiki/Singleton_(mathematics)">singleton sets</a>. </p> <p> I'm so happy that people like Bogdan Galiceanu share their thoughts with me, because it gives me a wider perspective on how programmers interact with APIs. If you take the API of <a href="https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection">the .NET Core DI Container</a> as given, you almost <em>have</em> to think of its entries in this way. </p> <p> I think, on the other hand, that this indicates a missed opportunity of API design. I replied: </p> <blockquote> <p> "Yes, this could be a requirement. I think, though, that if that's the case, you've unearthed another invariant. That's what object-oriented design is about. </p> <p> "Different invariants imply a change of type. If there can only be one of each element, then a set is more appropriate." </p> <footer><cite><a href="https://twitter.com/ploeh/status/1252226486507110400">(me)</a></cite></footer> </blockquote> <p> Twitter isn't a medium that makes it easy to elaborate on ideas, but what I meant was that if a container should contain only a single instance of, say, <code>IFoo</code>, it'd be clearer if the type system reflected that. Thus, when <a href="/2010/09/29/TheRegisterResolveReleasepattern">resolving</a> <code>IFoo</code>, the return type should be <code>IFoo</code>, and not <code>IEnumerable&lt;IFoo&gt;</code>. </p> <p> On the other hand, if you meant to <a href="/2010/09/29/TheRegisterResolveReleasepattern">register</a> a collection of <code>IBar</code> services, when resolving <code>IBar</code>, the return type should be <code>IEnumerable&lt;IBar&gt;</code> (or, <a href="/2013/07/20/linq-versus-the-lsp">even better</a>, <code>IReadOnlyCollection&lt;IBar&gt;</code>). </p> <p> The <code>Container</code> shown here has this desired property: You can't <code>insert</code> the same type more than once. If you want to <code>insert</code> multiple <code>IBar</code> values, you must <code>insert</code> a <code>[IBar]</code> (<em>list of <code>IBar</code></em>). Thus, you can't <code>get</code> a single <code>IBar</code>, but you can <code>get</code> a list: <code>[IBar]</code>. </p> <p> That was my motivation for the rule that each type can only appear once. In Haskell it's possible to implement such a rule at the type level. I don't think it'd be possible in a language like C# or <a href="https://fsharp.org">F#</a>, but you <em>could</em> implement it as a run-time check. </p> <h3 id="64add25aee0444b086b10bbfe0d48db3"> Conclusion <a href="#64add25aee0444b086b10bbfe0d48db3" title="permalink">#</a> </h3> <p> You can implement a type-level container of values in Haskell. The contents are completely parametrically polymorphic, so while you can insert pure values like <code>String</code>, <code>Bool</code>, or <code>Reservation</code> into it, you can also add functions and impure actions like <code>Reservation -&gt; IO ()</code>. </p> <p> Why is this interesting? It really isn't, apart from that I found it an interesting exercise in type-level programming. </p> <p> The idea of a type-safe DI Container is, however, marginally more compelling, so I'll return to that topic in a future article. </p> <p> <strong>Next:</strong> <a href="/2022/01/31/a-type-safe-di-container-c-example">A type-safe DI Container C# example</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Enumerate Wordle combinations with an applicative functor https://blog.ploeh.dk/2022/01/17/enumerate-wordle-combinations-with-an-applicative-functor 2022-01-17T16:39:00+00:00 Mark Seemann <div id="post"> <p> <em>An example of ad-hoc programming.</em> </p> <p> Like so many others, I recently started solving the daily <a href="https://www.powerlanguage.co.uk/wordle/">Wordle</a> puzzle. As is normal when one is a beginner, I initially struggled a bit. One day, I couldn't find a good word to proceed. </p> <p> To be clear, this article isn't really about Wordle strategies or tools. Rather, it's an example of ad-hoc programming. Particularly, it's an example of how the <a href="/2018/10/01/applicative-functors">applicative</a> nature of lists can be useful when you need to enumerate combinations. While I've <a href="/2018/10/15/an-applicative-password-list">previously shown a similar example</a>, I think one more is warranted. </p> <h3 id="aa6304fd821b47f5a67ec6ea9e7e5665"> Inured from tears <a href="#aa6304fd821b47f5a67ec6ea9e7e5665" title="permalink">#</a> </h3> <p> Last Monday, I'd started with the word <em>TEARS</em>. (I've subsequently learned that better starting words exist.) The puzzle responded with a yellow <em>E</em> and a green <em>R:</em> </p> <p> <img src="/content/binary/wordle-tears.png" alt="Wordle after entering TEARS."> </p> <p> In case you haven't played the game, this means that the fourth letter of the hidden word <em>is</em> an <em>R</em>, and that the word also contains an <em>E</em>. The second letter, however, is <em>not</em> an <em>E</em>. Also, the hidden word contains neither <em>T</em>, <em>A</em>, nor <em>S</em>. </p> <p> While the green and yellow letters may be repeated, you only have six guesses, so it's a good idea to attempt to exhaust as many letters as possible. The first compatible word with five distinct letters that I could think of was <em>INURE</em>. </p> <p> <img src="/content/binary/wordle-tears-inure.png" alt="Wordle after entering TEARS and INURE."> </p> <p> This gave me a bit of new information. The hidden word also contains a <em>U</em>, but not as the third letter. Furthermore, the <em>E</em> isn't the last letter either. Keep in mind that from <em>TEARS</em> we also know that <em>E</em> isn't the second letter. </p> <p> While I believe myself to have a decent English vocabulary, at this point I was stuck. While I knew that the <em>E</em> had to be in either first or third position, I couldn't think of a single word that fit all observations. </p> <p> After trying to come up with a word for ten minutes, I decided that, instead of giving up, I'd use the applicative nature of lists to generate all possible combinations. I was hoping that with the observations already in place, there wouldn't be too many to sift through. </p> <h3 id="c0745354a6364beaba9ac1a4423e1b9d"> Combinations <a href="#c0745354a6364beaba9ac1a4423e1b9d" title="permalink">#</a> </h3> <p> While you could do this in other languages (such as <a href="https://fsharp.org">F#</a> or C#), it's natural to use <a href="https://www.haskell.org">Haskell</a> because it natively understands applicative functors. Thus, I launched GHCi (<em>Glasgow Haskell Compiler interactive</em> - the Haskell <a href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">REPL</a>). </p> <p> Wordle is kind enough to show a keyboard with colour-coded keys: </p> <p> <img src="/content/binary/wordle-keyboard.png" alt="Wordle keyboard."> </p> <p> All letters except the dark ones remain valid, so I first defined a list of all available letters: </p> <p> <pre>&gt; avail = "QWERYUOPDFGHJKLZXCVBM"</pre> </p> <p> The variable <code>avail</code> is a <code>String</code>, but in Haskell, a <code>String</code> is a type synonym for a (linked) list of <code>Char</code> values (characters). Since lists form an applicative functor, that'll work. </p> <p> Most of the letters are still in play - only five letters are already out of the picture: <em>T</em>, <em>I</em>, <em>A</em>, <em>S</em>, and <em>N</em>. Thus, <code>avail</code>still spells out most of the alphabet. </p> <p> Next, I wrote an expression that enumerates all five-letter combinations of these letters, with one constraint: The fourth letter must be an <em>R:</em> </p> <p> <pre>&gt; candidates = (\x y z æ ø -&gt; [x,y,z,æ,ø]) &lt;$&gt; avail &lt;*&gt; avail &lt;*&gt; avail &lt;*&gt; "R" &lt;*&gt; avail</pre> </p> <p> The leftmost expression (<code>(\x y z æ ø -&gt; [x,y,z,æ,ø])</code>) is a lambda expression that takes five values (one from each list of available letters) and combines them to a single list. Each value (<code>x</code>, <code>y</code>, and so on) is a <code>Char</code> value, and since <code>String</code> in Haskell is the same as <code>[Char]</code>, the expression <code>[x,y,z,æ,ø]</code> is a <code>String</code>. In Danish we have three more letters after <code>z</code>, so I after I ran out of the the usual Latin letters, I just continued with the Danish <code>æ</code> and <code>ø</code>. </p> <p> Notice that between each of the <code>&lt;*&gt;</code> operators (<em>apply</em>) I've supplied the list of available letters. In the fourth position there's no choice, so there the list contains only a single letter. Recall that a <code>String</code> is a list of characters, so <code>"R"</code> is the same as <code>['R']</code>. </p> <p> How many combinations are there? Let's ask GHCi: </p> <p> <pre>&gt; length candidates 194481</pre> </p> <p> Almost 200,000. That's a bit much to look through, but we can peek at the first ten as a sanity check: </p> <p> <pre>&gt; take 10 candidates ["QQQRQ","QQQRW","QQQRE","QQQRR","QQQRY","QQQRU","QQQRO","QQQRP","QQQRD","QQQRF"]</pre> </p> <p> There are no promising words in this little list, but I never expected that. </p> <p> I needed to narrow down the options. </p> <h3 id="78f6d90a9b3a43649fa97f525b52f980"> Filtering <a href="#78f6d90a9b3a43649fa97f525b52f980" title="permalink">#</a> </h3> <p> How do you make a collection smaller? You could filter it. </p> <p> <code>candidates</code> contains illegal values. For example, the third value in the above list (of the ten first candidates) is <code>"QQQRE"</code>. Yet, we know (from the <em>INURE</em> attempt) that the last letter isn't <em>E</em>. We can filter out all strings that end with <code>E</code>: </p> <p> <pre>&gt; take 10 $ filter (\s -&gt; s!!4 /= 'E') candidates ["QQQRQ","QQQRW","QQQRR","QQQRY","QQQRU","QQQRO","QQQRP","QQQRD","QQQRF","QQQRG"]</pre> </p> <p> In Haskell, <code>!!</code> is the indexing operator, so <code>s!!4</code> means the (zero-based) fourth element of the string <code>s</code>. <code>/=</code> is the inequality operator, so the lambda expression <code>(\s -&gt; s!!4 /= 'E')</code> identifies all strings where the fifth element (or fourth element, when starting from zero) is different from <code>E</code>. </p> <p> We know more than this, though. We also know that the second element can't be <em>E</em>, and that the third element isn't <em>U</em>, so add those predicates to the <code>filter</code>: </p> <p> <pre>&gt; take 10 $ filter (\s -&gt; s!!1 /= 'E' && s!!2 /= 'U' && s!!4 /= 'E') candidates ["QQQRQ","QQQRW","QQQRR","QQQRY","QQQRU","QQQRO","QQQRP","QQQRD","QQQRF","QQQRG"]</pre> </p> <p> How many are left? </p> <p> <pre>&gt; length $ filter (\s -&gt; s!!1 /= 'E' && s!!2 /= 'U' && s!!4 /= 'E') candidates 168000</pre> </p> <p> Still too many, but we aren't done yet. </p> <p> Notice that all of the first ten values shown above are invalid. Why? Because the word must contain at least one <em>E</em>, and none of them do. Let's add that predicate: </p> <p> <pre>&gt; take 10 $ filter (\s -&gt; s!!1 /= 'E' && s!!2 /= 'U' && s!!4 /= 'E' && 'E' `elem` s) candidates ["QQERQ","QQERW","QQERR","QQERY","QQERU","QQERO","QQERP","QQERD","QQERF","QQERG"]</pre> </p> <p> The Boolean expression <code>'E' `elem` s</code> means that the character <code>'E'</code> must be an element of the string (list) <code>s</code>. </p> <p> The same rule applies for <em>U:</em> </p> <p> <pre>&gt; take 10 $ filter (\s -&gt; s!!1 /= 'E' && s!!2 /= 'U' && s!!4 /= 'E' && 'E' `elem` s && 'U' `elem` s) candidates ["QQERU","QWERU","QRERU","QYERU","QUERQ","QUERW","QUERR","QUERY","QUERU","QUERO"]</pre> </p> <p> There's a great suggestion already! The eighth entry spells <em>QUERY!</em> Let's try it: </p> <p> <img src="/content/binary/wordle-tears-inure-query.png" alt="Wordle after entering TEARS, INURE and QUERY."> </p> <p> <em>QUERY</em> was the word of the day! </p> <p> A bit embarrassing that I couldn't think of <em>query</em>, given that I often discuss <a href="https://en.wikipedia.org/wiki/Command%E2%80%93query_separation">Command Query Separation</a>. </p> <p> Was that just pure luck? How many suggestions are left in the filtered list? </p> <p> <pre>&gt; length $ filter (\s -&gt; s!!1 /= 'E' && s!!2 /= 'U' && s!!4 /= 'E' && 'E' `elem` s && 'U' `elem` s) candidates 1921</pre> </p> <p> Okay, a bit lucky. If I ask GHCi to display the filtered list in its entirety, no other word jumps out at me, looking like a real word. </p> <h3 id="8c5fd8c64959478bb7834274657af406"> Conclusion <a href="#8c5fd8c64959478bb7834274657af406" title="permalink">#</a> </h3> <p> While I admit that I was a bit lucky that <em>QUERY</em> was among the first ten of 1,921 possible combinations, I still find that applicative combinations are handy as an ad-hoc tool. I'm sure there are more elegant ways to solve a problem like this one, but for me, this approach had <a href="/2019/12/16/zone-of-ceremony">low ceremony</a>. It was a few lines of code in a terminal. Once I had the answer, I could just close the terminal and no further clean-up was required. </p> <p> I'm sure other people have other tool preferences, and perhaps you'd like to <a href="https://github.com/ploeh/ploeh.github.com#comments">leave a comment</a> to the effect that you have a better way with Bash, Python, or APL. That's OK, and I don't mind learning new tricks. </p> <p> I do find this capability of applicative functors to do combinatorics occasionally useful, though. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="22eb88afa50e4193b8f04e82c55df1cb"> <div class="comment-author"><a href="https://github.com/debonte">Erik De Bonte</a></div> <div class="comment-content"> <p> It's not "better", but here's a similar approach in Python. </p> <p> <pre>from operator import contains avail = "QWERYUOPDFGHJKLZXCVBM" candidates = ((x,y,z,æ,ø) for x in avail for y in avail for z in avail for æ in "R" for ø in avail) filtered = [s for s in candidates if s[1] != "E" and s[2] != "U" and s[4] != "E" and contains(s, "E") and contains(s, "U")] for candidate in filtered[:10]: print(*candidate, sep="")</pre> </p> </div> <div class="comment-date">2022-01-21 19:08 UTC</div> </div> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Type-safe DI composition https://blog.ploeh.dk/2022/01/10/type-safe-di-composition 2022-01-10T06:41:00+00:00 Mark Seemann <div id="post"> <p> <em>DI Containers aren't type-safe. What are the alternatives?</em> </p> <p> In April 2020 I published an article called <a href="/2020/04/20/unit-bias-against-collections">Unit bias against collections</a>. My goal with the article was to point out a common <a href="https://en.wikipedia.org/wiki/Cognitive_bias">cognitive bias</a>. I just happened to use .NET's built-in DI Container as an example because I'd recently encountered a piece of documentation that exhibited the kind of bias I wanted to write about. </p> <p> This lead to a discussion about the mental model of the DI Container: </p> <blockquote> <p> "Yeah, I wasn't explicit and clarified in a second tweet. I didn't mean in the services example, but in general where it helps if the reader's mental model of the code has 1 item from the collection, because that's how it is in real life. SingleOrDefault would enforce this." </p> <footer><cite><a href="https://twitter.com/bogdangaliceanu/status/1252210213211582477">Bogdan Galiceanu</a></cite></footer> </blockquote> <p> The point made by Bogdan Galiceanu highlights the incongruity between the container's API and the mental model required to work with it. </p> <h3 id="56c89a345b534a7d9cc4f90cd1779b89"> IServiceCollection recap <a href="#56c89a345b534a7d9cc4f90cd1779b89" title="permalink">#</a> </h3> <p> The API in case belongs to <a href="https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection">IServiceCollection</a>, which is little more than a collection of <a href="https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.servicedescriptor">ServiceDescriptor</a> objects. Each <code>ServiceDescriptor</code> describes a service, as the name implies. </p> <p> Given an <code>IServiceCollection</code> you can, for example, <a href="/2010/09/29/TheRegisterResolveReleasepattern">register</a> an <code>IReservationsRepository</code> instance: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">connStr</span>&nbsp;=&nbsp;Configuration.GetConnectionString(<span style="color:#a31515;">&quot;Restaurant&quot;</span>); services.AddSingleton&lt;IReservationsRepository&gt;(<span style="color:#1f377f;">sp</span>&nbsp;=&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">logger</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp.GetService&lt;ILogger&lt;LoggingReservationsRepository&gt;&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">postOffice</span>&nbsp;=&nbsp;sp.GetService&lt;IPostOffice&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;EmailingReservationsRepository( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;postOffice, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;LoggingReservationsRepository( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;SqlReservationsRepository(connStr))); });</pre> </p> <p> This adds a <code>ServiceDescriptor</code> entry to the collection. (Code examples are from <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.) </p> <p> Later, you can <a href="/2020/04/20/unit-bias-against-collections">remove and replace the service</a> for test purposes: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">SelfHostedApi</span>&nbsp;:&nbsp;WebApplicationFactory&lt;Startup&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">protected</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ConfigureWebHost</span>(IWebHostBuilder&nbsp;<span style="color:#1f377f;">builder</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;builder.ConfigureServices(<span style="color:#1f377f;">services</span>&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;services.RemoveAll&lt;IReservationsRepository&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;services.AddSingleton&lt;IReservationsRepository&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;FakeDatabase()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Here I use <code>RemoveAll</code>, even though I 'know' there's only one service of that type. Bogdan Galiceanu's argument, if I understand it correctly, is that it'd be more honest to use <code>SingleOrDefault</code>, since we 'know' that there's only one such service. </p> <p> I don't bring this up to bash on either Bogdan Galiceanu or the <code>IServiceCollection</code> API, but this exchange of ideas provided another example that <a href="/2012/11/06/WhentouseaDIContainer">DI Containers aren't as helpful as you'd think</a>. While they do provide some services, they require significant mental overhead. You have to 'know' that this service has only one instance, while another service may have two implementations, and so on. As the size of both code base and team grows, keeping all such knowledge in your head becomes increasingly difficult. </p> <p> The promise of object-orientation was always that you <em>shouldn't</em> have to remember implementation details. </p> <p> Particularly with statically typed programming languages you should be able to surface such knowledge as static type information. What would a more honest, statically typed DI Container look like? </p> <h3 id="5c487718a2f84c4c9f68f71871bf15e1"> Statically typed containers <a href="#5c487718a2f84c4c9f68f71871bf15e1" title="permalink">#</a> </h3> <p> Over a series of articles I'll explore how a statically typed DI Container might look: </p> <ul> <li><a href="/2022/01/24/type-level-di-container-prototype">Type-level DI Container prototype</a></li> <li><a href="/2022/01/31/a-type-safe-di-container-c-example">A type-safe DI Container C# example</a></li> <li><a href="/2022/02/07/nested-type-safe-di-containers">Nested type-safe DI Containers</a></li> <li><a href="/2022/02/21/a-type-safe-di-container-as-a-functor">A type-safe DI Container as a functor</a></li> <li><a href="/2022/03/07/a-type-safe-di-container-as-a-tuple">A type-safe DI Container as a tuple</a></li> <li><a href="/2022/03/14/type-safe-di-containers-are-redundant">Type-safe DI Containers are redundant</a></li> </ul> <p> The first of these articles show a <a href="https://www.haskell.org">Haskell</a> prototype, while the rest of the articles use C#. If you don't care about Haskell, you can skip the first article. </p> <p> As the title of the last article implies, this exploration only concludes that type-safe DI Containers are isomorphic to <a href="/2014/06/10/pure-di">Pure DI</a>. I consider Pure DI the simplest of these approaches, suggesting that there's no point in type-safe DI Containers of the kinds shown here. </p> <h3 id="10a5db047d7d4bc1b397214ba6db6137"> Conclusion <a href="#10a5db047d7d4bc1b397214ba6db6137" title="permalink">#</a> </h3> <p> Some people like DI Containers. I don't, because they take away type-safety without providing much benefit to warrant the trade-off. A commonly suggested benefit of DI Containers is lifetime management, but you can <a href="/2014/06/03/compile-time-lifetime-matching">trivially implement type-safe lifetime management with Pure DI</a>. I don't find that argument compelling. </p> <p> This article series examines if it's possible to create a 'better' DI Container by making it more type-safe, but I ultimately conclude that there's no point in doing so. </p> <p> <strong>Next:</strong> <a href="/2022/01/24/type-level-di-container-prototype">Type-level DI Container prototype</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. To ID or not to ID https://blog.ploeh.dk/2022/01/03/to-id-or-not-to-id 2022-01-03T08:57:00+00:00 Mark Seemann <div id="post"> <p> <em>How to model an ID that sometimes must be present, and sometimes not.</em> </p> <p> I'm currently writing a client library for <a href="https://www.criipto.com">Criipto</a> that partially implements the actions available on the <a href="https://fusebit.io/docs/reference/fusebit-http-api/">Fusebit API</a>. This article, however, isn't about the Fusebit API, so even if you don't know what that is, read on. The Fusebit API is just an example. </p> <p> This article, rather, is about how to model the absence or presence of an <code>Id</code> property. </p> <h3 id="76bfa54c15f346689e7210a9e5dc9852"> User example <a href="#76bfa54c15f346689e7210a9e5dc9852" title="permalink">#</a> </h3> <p> The Fusebit API is an HTTP API that, as these things usually do, enables you to create, read, update, and delete resources. One of these is a <em>user</em>. When you create a user, you supply such data as <code>firstName</code>, <code>lastName</code>, and <code>primaryEmail</code>: </p> <p> <pre>POST /v1/account/acc-123/user HTTP/2 authorization: Bearer 938[...] content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;firstName&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Rhea&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;lastName&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Curran&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;primaryEmail&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;recurring@example.net&quot;</span> } HTTP/2 200 content-type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;usr-8babf0cb95d94e6f&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;firstName&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Rhea&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;lastName&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Curran&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;primaryEmail&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;recurring@example.net&quot;</span> }</pre> </p> <p> Notice that you're supposed to <code>POST</code> the user representation <em>without</em> an ID. The response, however, contains an updated representation of the resource that now includes an <code>id</code>. The <code>id</code> (in this example <code>usr-8babf0cb95d94e6f</code>) was created by the service. </p> <p> To summarise: when you create a new user, you can't supply an ID, but once the user is created, it does have an ID. </p> <p> I wanted to capture this rule with the <a href="https://fsharp.org">F#</a> type system. </p> <h3 id="2f67ed9643b74c11b12054176540f9ea"> Inheritance <a href="#2f67ed9643b74c11b12054176540f9ea" title="permalink">#</a> </h3> <p> Before we get to the F# code, let's take a detour around some typical C# code. </p> <p> At times, I've seen people address this kind of problem by having two types: <code>UserForCreation</code> and <code>CreatedUser</code>, or something like that. The only difference would be that <code>CreatedUser</code> would have an <code>Id</code> property, whereas <code>UserForCreation</code> wouldn't. While, at this time, the <a href="https://en.wikipedia.org/wiki/Rule_of_three_(computer_programming)">rule of three</a> doesn't apply yet, such duplication still seems frivolous. </p> <p> How does an object-oriented programmer address such a problem? By deriving <code>CreatedUser</code> from <code>UserForCreation</code>, of course! </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">CreatedUser</span>&nbsp;:&nbsp;UserForCreation { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>&nbsp;Id&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} }</pre> </p> <p> I'm not too fond of inheritance, and such a design also comes with a built-in flaw: Imagine a method with the signature <code>public CreatedUser Create(UserForCreation user)</code>. While such an API design clearly indicates that you don't <em>have</em> to supply an ID, you still can. You can call such a <code>Create</code> method with a <code>CreatedUser</code> object, since <code>CreatedUser</code> derives from <code>UserForCreation</code>. </p> <p> <pre>CreatedUser&nbsp;<span style="color:#1f377f;">user</span>&nbsp;=&nbsp;resource.Create(<span style="color:blue;">new</span>&nbsp;CreatedUser { &nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;<span style="color:#a31515;">&quot;123&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;FirstName&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Sue&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;LastName&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Flay&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;<span style="color:#a31515;">&quot;suoffle@example.org&quot;</span> });</pre> </p> <p> Since <code>CreatedUser</code> contains an ID, this seems to suggest that you can call the <code>Create</code> method with a user with an ID. What would you expected from such a possibility? In the above code example, what would you expect the value of <code>user.Id</code> to be? </p> <p> It'd be reasonable to expect <code>user.Id</code> to be <code>"123"</code>. This seems to indicate that it'd be possible to supply a client-generated user ID, which would then be used instead of a server-generated user ID. The HTTP API, however, doesn't allow that. </p> <p> Such a design is misleading. It suggests that <code>CreatedUser</code> can be used where <code>UserForCreation</code> is required. This isn't true. </p> <h3 id="cf4f25d849d7436686852f177cff2578"> Generic user <a href="#cf4f25d849d7436686852f177cff2578" title="permalink">#</a> </h3> <p> I was aware of the above problem, so I didn't even attempt to go there. Besides, I was writing the library in F#, not C#, and while F# enables inheritance as well, it's not the first modelling option you'd typically reach for. </p> <p> Instead, my first attempt was to define user data as a generic record type: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;UserData&lt;&#39;a&gt;&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;:&nbsp;&#39;a &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FirstName&nbsp;:&nbsp;string&nbsp;option &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LastName&nbsp;:&nbsp;string&nbsp;option &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;:&nbsp;MailAddress&nbsp;option &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Identities&nbsp;:&nbsp;Identity&nbsp;list &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permissions&nbsp;:&nbsp;Permission&nbsp;list &nbsp;&nbsp;&nbsp;&nbsp;}</pre> </p> <p> (The Fusebit API also enables you to supply <code>Identities</code> and <code>Permissions</code> when creating a user. I omitted them from the above C# example code because this detail is irrelevant to the example.) </p> <p> This enabled me to define an impure action to create a user: </p> <p> <pre><span style="color:green;">//&nbsp;ApiClient&nbsp;-&gt;&nbsp;UserData&lt;unit&gt;&nbsp;-&gt;&nbsp;Task&lt;Result&lt;UserData&lt;string&gt;,&nbsp;HttpResponseMessage&gt;&gt;</span> <span style="color:blue;">let</span>&nbsp;create&nbsp;client&nbsp;(userData&nbsp;:&nbsp;UserData&lt;unit&gt;)&nbsp;=&nbsp;task&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;jobj&nbsp;=&nbsp;JObject&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;userData.FirstName &nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.iter&nbsp;(<span style="color:blue;">fun</span>&nbsp;fn&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;jobj.[<span style="color:#a31515;">&quot;firstName&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span>&nbsp;JValue&nbsp;fn) &nbsp;&nbsp;&nbsp;&nbsp;userData.LastName &nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.iter&nbsp;(<span style="color:blue;">fun</span>&nbsp;ln&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;jobj.[<span style="color:#a31515;">&quot;lastName&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span>&nbsp;JValue&nbsp;ln) &nbsp;&nbsp;&nbsp;&nbsp;userData.Email &nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.iter &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:blue;">fun</span>&nbsp;email&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;jobj.[<span style="color:#a31515;">&quot;primaryEmail&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span>&nbsp;email&nbsp;|&gt;&nbsp;string&nbsp;|&gt;&nbsp;JValue) &nbsp;&nbsp;&nbsp;&nbsp;jobj.[<span style="color:#a31515;">&quot;identities&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userData.Identities &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.map&nbsp;Identity.toJToken &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.toArray &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;JArray &nbsp;&nbsp;&nbsp;&nbsp;jobj.[<span style="color:#a31515;">&quot;access&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;aobj&nbsp;=&nbsp;JObject&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aobj.[<span style="color:#a31515;">&quot;allow&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userData.Permissions &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.map&nbsp;Permission.toJToken &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.toArray &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;JArray &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aobj &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;json&nbsp;=&nbsp;jobj.ToString&nbsp;Formatting.None &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;relativeUrl&nbsp;=&nbsp;Uri&nbsp;(<span style="color:#a31515;">&quot;user&quot;</span>,&nbsp;UriKind.Relative) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;resp&nbsp;=&nbsp;Api.post&nbsp;client&nbsp;relativeUrl&nbsp;json &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;resp.IsSuccessStatusCode &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">then</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;content&nbsp;=&nbsp;resp.Content.ReadAsStringAsync&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;jtok&nbsp;=&nbsp;JToken.Parse&nbsp;content &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;createdUser&nbsp;=&nbsp;parseUser&nbsp;jtok &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;Ok&nbsp;createdUser &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">else</span>&nbsp;<span style="color:blue;">return</span>&nbsp;Error&nbsp;resp&nbsp;}</pre> </p> <p> Where <code>parseUser</code> is defined like this: </p> <p> <pre><span style="color:green;">//&nbsp;JToken&nbsp;-&gt;&nbsp;UserData&lt;string&gt;</span> <span style="color:blue;">let</span>&nbsp;<span style="color:blue;">private</span>&nbsp;parseUser&nbsp;(jobj&nbsp;:&nbsp;JToken)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;uid&nbsp;=&nbsp;jobj.[<span style="color:#a31515;">&quot;id&quot;</span>]&nbsp;|&gt;&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;fn&nbsp;=&nbsp;jobj.[<span style="color:#a31515;">&quot;firstName&quot;</span>]&nbsp;|&gt;&nbsp;Option.ofObj&nbsp;|&gt;&nbsp;Option.map&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;ln&nbsp;=&nbsp;jobj.[<span style="color:#a31515;">&quot;lastName&quot;</span>]&nbsp;|&gt;&nbsp;Option.ofObj&nbsp;|&gt;&nbsp;Option.map&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;email&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jobj.[<span style="color:#a31515;">&quot;primaryEmail&quot;</span>] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.ofObj &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.map&nbsp;(string&nbsp;&gt;&gt;&nbsp;MailAddress) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;uid &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FirstName&nbsp;=&nbsp;fn &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LastName&nbsp;=&nbsp;ln &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;email &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Identities&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permissions&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;}</pre> </p> <p> Notice that, if we strip away all the noise from the <code>User.create</code> action, it takes a <code>UserData&lt;unit&gt;</code> as input and returns a <code>UserData&lt;string&gt;</code> as output. </p> <p> Creating a value of a type like <code>UserData&lt;unit&gt;</code> seems a little odd: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;user&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FirstName&nbsp;=&nbsp;Some&nbsp;<span style="color:#a31515;">&quot;Helen&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LastName&nbsp;=&nbsp;Some&nbsp;<span style="color:#a31515;">&quot;Back&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;Some&nbsp;(MailAddress&nbsp;<span style="color:#a31515;">&quot;hellnback@example.net&quot;</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Identities&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permissions&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;}</pre> </p> <p> It gets the point across, though. In order to call <code>User.create</code> you must supply a <code>UserData&lt;unit&gt;</code>, and the only way you can do that is by setting <code>Id</code> to <code>()</code>. </p> <h3 id="6b269340404e4dbeaba049d65886edf2"> Not quite there... <a href="#6b269340404e4dbeaba049d65886edf2" title="permalink">#</a> </h3> <p> In the Fusebit API, however, the <em>user</em> resource isn't the only resource that exhibits the pattern of requiring no ID on creation, but having an ID after creation. Another example is a resource called a <em>client</em>. Adopting the above design as a template, I also defined <code>ClientData</code> as a generic record type: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;ClientData&lt;&#39;a&gt;&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;:&nbsp;&#39;a &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DisplayName&nbsp;:&nbsp;string&nbsp;option &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Identities&nbsp;:&nbsp;Identity&nbsp;list &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permissions&nbsp;:&nbsp;Permission&nbsp;list &nbsp;&nbsp;&nbsp;&nbsp;}</pre> </p> <p> In both cases, I also realised that the record types gave rise to <a href="/2018/03/22/functors">functors</a>. A <code>map</code> function turned out to be useful in certain unit tests, so I added such functions as well: </p> <p> <pre><span style="color:blue;">module</span>&nbsp;Client&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;map&nbsp;f&nbsp;c&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;f&nbsp;c.Id &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DisplayName&nbsp;=&nbsp;c.DisplayName &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Identities&nbsp;=&nbsp;c.Identities &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permissions&nbsp;=&nbsp;c.Permissions &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</pre> </p> <p> The corresponding <code>User.map</code> function was similar, so I began to realise that I had some boilerplate on my hands. </p> <p> Besides, a type like <code>UserData&lt;'a&gt;</code> seems to indicate that the type argument <code>'a</code> could be anything. The <code>map</code> function implies that as well. In reality, though, the only constructed types you'd be likely to run into are <code>UserData&lt;unit&gt;</code> and <code>UserData&lt;string&gt;</code>. </p> <p> I wasn't quite happy with this design, after all... </p> <h3 id="c74641d5b7fc49849d671f233f77bf37"> Identifiable <a href="#c74641d5b7fc49849d671f233f77bf37" title="permalink">#</a> </h3> <p> After thinking about this, I decided to move the generics around. Instead of making the ID generic, I instead made the payload generic by introducing this container type: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;Identifiable&lt;&#39;a&gt;&nbsp;=&nbsp;{&nbsp;Id&nbsp;:&nbsp;string;&nbsp;Item&nbsp;:&nbsp;&#39;a&nbsp;}</pre> </p> <p> The <code>User.create</code> action now looks like this: </p> <p> <pre><span style="color:green;">//&nbsp;ApiClient&nbsp;-&gt;&nbsp;UserData&nbsp;-&gt;&nbsp;Task&lt;Result&lt;Identifiable&lt;UserData&gt;,&nbsp;HttpResponseMessage&gt;&gt;</span> <span style="color:blue;">let</span>&nbsp;create&nbsp;client&nbsp;userData&nbsp;=&nbsp;task&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;jobj&nbsp;=&nbsp;JObject&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;userData.FirstName &nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.iter&nbsp;(<span style="color:blue;">fun</span>&nbsp;fn&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;jobj.[<span style="color:#a31515;">&quot;firstName&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span>&nbsp;JValue&nbsp;fn) &nbsp;&nbsp;&nbsp;&nbsp;userData.LastName &nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.iter&nbsp;(<span style="color:blue;">fun</span>&nbsp;ln&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;jobj.[<span style="color:#a31515;">&quot;lastName&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span>&nbsp;JValue&nbsp;ln) &nbsp;&nbsp;&nbsp;&nbsp;userData.Email &nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.iter &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:blue;">fun</span>&nbsp;email&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;jobj.[<span style="color:#a31515;">&quot;primaryEmail&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span>&nbsp;email&nbsp;|&gt;&nbsp;string&nbsp;|&gt;&nbsp;JValue) &nbsp;&nbsp;&nbsp;&nbsp;jobj.[<span style="color:#a31515;">&quot;identities&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userData.Identities &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.map&nbsp;Identity.toJToken &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.toArray &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;JArray &nbsp;&nbsp;&nbsp;&nbsp;jobj.[<span style="color:#a31515;">&quot;access&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;aobj&nbsp;=&nbsp;JObject&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aobj.[<span style="color:#a31515;">&quot;allow&quot;</span>]&nbsp;<span style="color:blue;">&lt;-</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userData.Permissions &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.map&nbsp;Permission.toJToken &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.toArray &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;JArray &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aobj &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;json&nbsp;=&nbsp;jobj.ToString&nbsp;Formatting.None &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;relativeUrl&nbsp;=&nbsp;Uri&nbsp;(<span style="color:#a31515;">&quot;user&quot;</span>,&nbsp;UriKind.Relative) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;resp&nbsp;=&nbsp;Api.post&nbsp;client&nbsp;relativeUrl&nbsp;json &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;resp.IsSuccessStatusCode &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">then</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;content&nbsp;=&nbsp;resp.Content.ReadAsStringAsync&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;jtok&nbsp;=&nbsp;JToken.Parse&nbsp;content &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;createdUser&nbsp;=&nbsp;parseUser&nbsp;jtok &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;Ok&nbsp;createdUser &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">else</span>&nbsp;<span style="color:blue;">return</span>&nbsp;Error&nbsp;resp&nbsp;}</pre> </p> <p> Where <code>parseUser</code> is defined as: </p> <p> <pre><span style="color:green;">//&nbsp;JToken&nbsp;-&gt;&nbsp;Identifiable&lt;UserData&gt;</span> <span style="color:blue;">let</span>&nbsp;<span style="color:blue;">private</span>&nbsp;parseUser&nbsp;(jtok&nbsp;:&nbsp;JToken)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;uid&nbsp;=&nbsp;jtok.[<span style="color:#a31515;">&quot;id&quot;</span>]&nbsp;|&gt;&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;fn&nbsp;=&nbsp;jtok.[<span style="color:#a31515;">&quot;firstName&quot;</span>]&nbsp;|&gt;&nbsp;Option.ofObj&nbsp;|&gt;&nbsp;Option.map&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;ln&nbsp;=&nbsp;jtok.[<span style="color:#a31515;">&quot;lastName&quot;</span>]&nbsp;|&gt;&nbsp;Option.ofObj&nbsp;|&gt;&nbsp;Option.map&nbsp;string &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;email&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jtok.[<span style="color:#a31515;">&quot;primaryEmail&quot;</span>] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.ofObj &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.map&nbsp;(string&nbsp;&gt;&gt;&nbsp;MailAddress) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;ids&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">match</span>&nbsp;jtok.[<span style="color:#a31515;">&quot;identities&quot;</span>]&nbsp;<span style="color:blue;">with</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;<span style="color:blue;">null</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;x&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;x&nbsp;:?&gt;&nbsp;JArray&nbsp;|&gt;&nbsp;Seq.map&nbsp;Identity.parse&nbsp;|&gt;&nbsp;Seq.toList &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;perms&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jtok.[<span style="color:#a31515;">&quot;access&quot;</span>] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.ofObj &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Option.toList &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;List.collect&nbsp;(<span style="color:blue;">fun</span>&nbsp;j&nbsp;<span style="color:blue;">-&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j.[<span style="color:#a31515;">&quot;allow&quot;</span>]&nbsp;:?&gt;&nbsp;JArray &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Seq.choose&nbsp;Permission.tryParse &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&gt;&nbsp;Seq.toList) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;uid &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FirstName&nbsp;=&nbsp;fn &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LastName&nbsp;=&nbsp;ln &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;email &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Identities&nbsp;=&nbsp;ids &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permissions&nbsp;=&nbsp;perms &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}</pre> </p> <p> The required input to <code>User.create</code> is now a simple, non-generic <code>UserData</code> value, and the successful return value an <code>Identifiable&lt;UserData&gt;</code>. There's no more arbitrary ID data types. The ID is either present as a <code>string</code> or it's absent. </p> <p> You could also turn the <code>Identifiable</code> container into a functor if you need it, but I've found no need for it so far. Wrapping and unwrapping the payload from the container is easy without supporting machinery like that. </p> <p> This design is still reusable. The equivalent <code>Client.create</code> action takes a non-generic <code>ClientData</code> value as input and returns an <code>Identifiable&lt;ClientData&gt;</code> value when successful. </p> <h3 id="9ff91e0a956147c796329551aa91bd1d"> C# translation <a href="#9ff91e0a956147c796329551aa91bd1d" title="permalink">#</a> </h3> <p> There's nothing F#-specific about the above solution. You can easily define <code>Identifiable</code> in C#: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Identifiable</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Identifiable</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">id</span>,&nbsp;T&nbsp;<span style="color:#1f377f;">item</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;id; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item&nbsp;=&nbsp;item; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>&nbsp;Id&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;Item&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;Identifiable&lt;T&gt;&nbsp;<span style="color:#1f377f;">identifiable</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;==&nbsp;identifiable.Id&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;T&gt;.Default.Equals(Item,&nbsp;identifiable.Item); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;HashCode.Combine(Id,&nbsp;Item); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> I've here used the explicit <code>class</code>-based syntax to define an immutable class. In C# 9 and later, you can simplify this quite a bit using <code>record</code> syntax instead (which gets you closer to the F# example), but I chose to use the more verbose syntax for the benefit of readers who may encounter this example and wish to understand how it relates to a less specific C-based language. </p> <h3 id="8df883ff44924387aafe519c5e83a178"> Conclusion <a href="#8df883ff44924387aafe519c5e83a178" title="permalink">#</a> </h3> <p> When you need to model interactions where you <em>must not</em> supply an ID on create, but representations have IDs when you query the resources, don't reach for inheritance. Wrap the data in a generic container that contains the ID and a generic payload. You can do this in languages that support parametric polymorphism (AKA <em>generics</em>). </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Label persistent test data with deletion dates https://blog.ploeh.dk/2021/12/27/label-persistent-test-data-with-deletion-dates 2021-12-27T06:34:00+00:00 Mark Seemann <div id="post"> <p> <em>If you don't clean up after yourself, at least enable others to do so.</em> </p> <p> I'm currently developing a software library that interacts with a third-party HTTP API to automate creation of various resources at that third party. While I use automated testing to verify that my code works, I still need to run my automation code against the real service once in while. After all, I'd like to verify that I've correctly interpreted the third party's documentation. </p> <p> I run my tests against a staging environment. The entire purpose of the library is to create resources, so all successful tests leave behind new 'things' in that staging environment. </p> <p> I'm not the only person who's testing against that environment, so all sorts of test entries accumulate. </p> <h3 id="f5fe2c5bcb104f65ad2f2e23ec5eea04"> Test data accretion <a href="#f5fe2c5bcb104f65ad2f2e23ec5eea04" title="permalink">#</a> </h3> <p> More than one developer is working with the third-party staging environment. They create various records in the system for test purposes. Often, they forget about these items once the test is complete. </p> <p> After a few weeks, you have various entries like these: </p> <ul> <li>Foo test Permit Client</li> <li>Fo Permit test client</li> <li>Paul Fo client from ..id</li> <li>Paul Verify Bar Test Client</li> <li>Pauls test</li> <li>SomeClient</li> <li>michael-template-client</li> </ul> <p> Some of these may be used for sustained testing. Others look suspiciously like abandoned objects. </p> <p> Does it matter that stuff like this builds up? </p> <p> Perhaps not, but it bothers my sense of order. If enough stuff builds up, it may also make it harder to find the item you actually need, and rarely, there may be real storage costs associated with the jetsam. But realistically, it just offends my proclivity for tidiness. </p> <h3 id="f83b07e2a587427db7d48e160ec09478"> Label ephemeral objects explicitly <a href="#f83b07e2a587427db7d48e160ec09478" title="permalink">#</a> </h3> <p> While I was testing my library's ability to create new resources, it dawned on me that I could use the records' display names to explicitly label them as temporary. </p> <p> At first, I named the objects like this: </p> <blockquote> Test by Mark Seemann. Delete if older than 10 minutes. </blockquote> <p> While browsing the objects via a web UI (instead of the HTTP API), however, I realised that the creation date wasn't visible in the UI. That makes it hard to identify the actual age. </p> <p> So, instead, I began labelling the items with a absolute time of safe deletion: </p> <blockquote> Test by Mark Seemann. Delete after 2021-11-23T13:13:00Z. </blockquote> <p> I chose to use <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> Zulu time because it's unambiguous. </p> <h3 id="deec7068de60499ab54fe3b9f011b5ed"> Author name <a href="#deec7068de60499ab54fe3b9f011b5ed" title="permalink">#</a> </h3> <p> As you can tell from the above examples, I explicitly named the object <em>Test by Mark Seemann</em>. The word <em>Test</em> indicates to everyone else that this is a test resource. The reason I decided to include my own name was to make it clear to other readers who to contact in case of doubt. </p> <p> While I find a message like <em>Delete after 2021-11-23T13:13:00Z</em> quite clear, you can never predict how other readers will interpret a text. Thus, I left my name in the title to give other people an opportunity to contact me if they have questions about the record. </p> <h3 id="81ea8d84900049a3b7155e22f5dfe06c"> Conclusion <a href="#81ea8d84900049a3b7155e22f5dfe06c" title="permalink">#</a> </h3> <p> This is just a little pleasantry you can use to make life for a development team a little more agreeable. </p> <p> You may not always be able to explicitly label a test item. Some records don't have display names, or the name field is too short to allow a detailed, explicit label. </p> <p> You may also feel that this isn't worth the trouble, and perhaps it isn't. </p> <p> I usually clean up after having added test data, but sometimes one forgets. When working in a shared environment, I find it considerate to clearly label test data to indicate to others when it's safe to delete it. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Changing your organisation https://blog.ploeh.dk/2021/12/20/changing-your-organisation 2021-12-20T06:41:00+00:00 Mark Seemann <div id="post"> <p> <em>Or: How do I convince X to adopt Y in software development?</em> </p> <p> In January 2012 a customer asked for my help with software architecture. The CTO needed to formulate a strategy to deal with increasing demand for bring-your-own-device (BYOD) access to internal systems. Executives brought their iPhones and iPads to work and expected to be able to access and interact with custom-developed and bespoke internal line-of-business applications. </p> <p> Quite a few of these were running on the Microsoft stack, which was the reason Microsoft Denmark had recommended me. </p> <p> I had several meetings with the developers responsible for enabling BYOD. One guy, in particular, kept suggesting a <a href="https://en.wikipedia.org/wiki/Microsoft_Silverlight">Silverlight</a> solution. I pointed out that Silverlight wouldn't run on Apple devices, but he wouldn't be dissuaded. He was <em>certain</em> that this was the correct solution, and I could tell that he became increasingly frustrated with me because he couldn't convince me. </p> <p> We'll return to this story later in this essay. </p> <h3 id="2346cc0e812841c483afd6483bb4b081"> Please convince my manager <a href="#2346cc0e812841c483afd6483bb4b081" title="permalink">#</a> </h3> <p> Sometimes people ask me questions like these: </p> <ul> <li>How do I convince my manager to let me use <a href="https://fsharp.org">F#</a>?</li> <li>How do I convince my team mates to adopt test-driven development?</li> <li>How do I convince the entire team that code quality matters?</li> </ul> <p> Sometimes I receive such questions via email. Sometimes people ask me at conferences or user groups. </p> <p> To quote <a href="https://ericlippert.com">Eric Lippert</a>: <a href="https://ericlippert.com/2012/12/17/performance-rant">Why are you even asking me?</a> </p> <p> To be fair, I do understand why people ask me, but I have few good answers. </p> <h3 id="8e3d3323c2c14cd2b592854140d2bb92"> Why ask me? <a href="#8e3d3323c2c14cd2b592854140d2bb92" title="permalink">#</a> </h3> <p> I suppose people ask me because I've been writing about software improvement for decades. <a href="/">This blog</a> dates back to January 2009, and <a href="http://blogs.msdn.com/ploeh">my previous MSDN blog</a> goes back to January 2006. These two resources alone contain more than 700 posts, the majority of which are about some kind of suggested improvement. Granted, there's also <a href="/2013/02/04/BewareofProductivityTools">the occasional rant</a>, by I think it's fair to say that my main motivation for writing is to share with readers what I think is right and good. </p> <p> I do write a lot about potential improvements to software development. </p> <p> As most readers have discovered, <a href="/dippp">my book about Dependency Injection</a> (with <a href="https://blogs.cuttingedge.it/steven/about/">Steven van Deursen</a>) is more than just a manual to a few Dependency Injection Containers, and my new book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> is full of suggested improvements. </p> <p> Add to that <a href="/pluralsight-courses">my Pluralsight courses</a>, <a href="https://cleancoders.com/videos/humane-code-real">my Clean Coders videos</a>, and <a href="/schedule">my conference talks</a>, and there's a clear pattern to most of my content. </p> <h3 id="b7902ef70c88416886f79138d5e4ee2a"> Maven <a href="#b7902ef70c88416886f79138d5e4ee2a" title="permalink">#</a> </h3> <p> In <a href="http://amzn.to/18sHRmt">The Tipping Point</a> Malcolm Gladwell presents a model for information dissemination, containing three types of people required for an idea to take hold: Connectors, mavens, and salesmen. </p> <p> In that model, a <em>maven</em> is an 'information specialist' - someone who accumulates knowledge and shares it with others. If I resemble any of these three types of people, I'm a maven. I like learning and discovering new ways of doing things, and obviously I like sharing that information. I wouldn't have blogged consistently for sixteen years if I didn't <a href="/2021/03/22/the-dispassionate-developer">feel compelled</a> to do so. </p> <p> My role, as I see it, is to find and discover better ways of writing software. Much of what I write about is something that I've picked up somewhere else, but I try to present it in my own way, and I'm diligent about citing sources. </p> <p> When people ask me concrete questions, like <em>how do I refactor this piece of code?</em> or <em>how do write this in a more functional style?</em>, I present an answer (if I can). </p> <p> The suggestions I make are just that: It's a buffet of possible solutions to certain problems. If you encounter one of my articles and find the proposed technique useful, then that makes me happy and proud. </p> <p> Notice the order of events: Someone has a problem, finds my content, and decides that it looks like a solution. Perhaps (s)he remembers my name. Perhaps (s)he feels that I helped solve a problem. </p> <p> Audience members that come to my conference talks, or readers who buy my books, may not have a concrete problem to solve, but they still voluntarily seeks me out - perhaps because of previous exposure to my content. </p> <p> To reiterate: </p> <ul> <li>You have a problem (concrete or vague)</li> <li>Perhaps you come across my content</li> <li>Perhaps you find it useful</li> </ul> <p> Perhaps you think that I convinced you that 'my way' is best. I didn't. You were already looking for a solution. You were ready for a change. You were open. </p> <h3 id="332746ebf9b249118eaf61d8a52cb2ec"> Salesman <a href="#332746ebf9b249118eaf61d8a52cb2ec" title="permalink">#</a> </h3> <p> When you ask me about how to convince your manager, or your team mates, you're no longer asking me a technical question. Now you're asking about <a href="https://amzn.to/32xc9X5">how to win friends and influence people</a>. You don't need a maven for that; you need a <em>salesman</em>. That's not me. </p> <p> I've had some success applying changes to software organisations, but in all cases, the reason I was there in the first place was because the organisation itself (or members thereof) had asked me to come and help them. When people <em>want</em> your help changing things, convincing them to try something new isn't a hard sell. </p> <p> When I consult development teams, I'm not there to sell them new processes; I'm there to help them use appropriate solutions at opportune moments. </p> <p> I'm not a salesman. Just because I convinced <em>you</em> that, say, property-based testing is a good idea doesn't mean I can convince anyone else. Keep in mind that I probably convinced you because you were ready for a change. </p> <p> Your manager or your team mates may not be. </p> <h3 id="2ce7188e30d64d318293fa17bd6da8dc"> Bide your time <a href="#2ce7188e30d64d318293fa17bd6da8dc" title="permalink">#</a> </h3> <p> While I'm no salesman, I've managed to turn people around from time to time. The best strategy, I've found, is to wait for an opportunity. </p> <p> As long as everything is going well, people aren't ready to change. </p> <blockquote> <p> "Only a crisis - actual or perceived - produces real change. When that crisis occurs, the actions that are taken depend on the ideas that are lying around. That, I believe, is our basic function: to develop alternatives to existing policies, to keep them alive and available until the politically impossible becomes the politically inevitable" </p> <footer><a href="https://amzn.to/3BsIqLG">Milton Friedman</a></footer> </blockquote> <p> If you have solutions at the ready, you may be able to convince your manager or your colleagues to try something new if a crisis occurs. Don't gloat - just present your suggestion: <em>What if we did this instead?</em> </p> <h3 id="3980ee0c37454d00b749c6a3ae51ab21"> Vocabulary <a href="#3980ee0c37454d00b749c6a3ae51ab21" title="permalink">#</a> </h3> <p> Indeed, I'm not a salesman, and while I can't tell you how to <em>sell</em> an idea to an unwilling audience, I <em>can</em> tell you how you can weaken your position: Make it all about you. </p> <p> Notice how questions like the above are often phrased: <em>my manager will not let me...</em> or <em>how do I convince my colleagues?</em> </p> <p> <a href="https://www.goodreads.com/review/show/1313490263">I actually didn't much like <em>How to Win Friends and Influence People</em></a>, but it does present the insight that in order to sway people, you have to consider what's in it for them. </p> <p> I had to be explicitly told this before I learned that lesson. </p> <p> In the second half of the 2000s I was attached to a software development project at a large Danish company. After a code review, I realised that the architecture of the code was <em>all wrong!</em> </p> <p> In order to make the project manager aware of the issue, I wrote an eight-page internal 'white paper' and emailed it to the project manager (let's call him Henk). </p> <p> Nothing happened. No one addressed the problem. </p> <p> A few weeks later, I had a scheduled one-on-one meeting with my own manager in Microsoft, and when asked if I had any issues, I started to complain about this problem I'd identified. </p> <p> My manager looked at me for a moment and asked me: <em>How do you think receiving that email made Henk feel?</em> </p> <p> It had never crossed my mind to think about that. It was <em>my</em> problem! <em>I</em> discovered it! I viewed myself as a great programmer and architect because I had perceived such a complex issue and was able to describe it clearly. It was all about me, me, me. </p> <p> When we programmers ask how to convince our managers to 'let us' use TDD, or FP, or some other 'cool' practice, we're still focused on <em>us</em>. What's in it for the manager? </p> <p> When we talk about code quality and lack thereof, 'ugly code', refactoring, and other such language, a non-coding manager is likely to see us as primadonnas out of touch with reality: <em>We have features to ship, but the programmers only care about making the code 'pretty'.</em> </p> <p> I offer no silver bullet to convince other people that certain techniques are superior, but do consider introducing suggestions by describing the benefits they bring: <em>Wouldn't it be cool if we could decrease our testing phase from three weeks to three days?</em>, <em>Wouldn't it be nice if we could deploy every week?</em>, <em>Wouldn't it be nice if we could decrease the number of errors our users encounter?</em> </p> <h3 id="b98c57c52d06414d8d74d40cfea69056"> You could be wrong <a href="#b98c57c52d06414d8d74d40cfea69056" title="permalink">#</a> </h3> <p> Have you ever felt frustrated that you couldn't convince other people to do it your way, despite <em>knowing</em> that you were right? </p> <p> Recall the developer from the introduction, the one who kept insisting that Silverlight was the right solution to the organisation's BYOD problem. He was clearly convinced that he had the solution, and he was frustrated that I kept rejecting it. </p> <p> We may scoff at such obvious ignorance of facts, but he had clearly drunk the Microsoft Kool-Aid. I could tell, because I'd been there myself. When you're a young programmer, you may easily buy into a compelling narrative. Microsoft evangelists were quite good at their game back then, as I suppose their Apple and Linux counterparts were and are. As an inexperienced developer, you can easily be convinced that a particular technology will solve all problems. </p> <p> When you're young and inexperienced, you can easily feel that you're absolutely right and still be unequivocally wrong. </p> <p> Consider this the next time you push your agenda. Perhaps your manager and colleagues reject your ideas because they're actually bad. A bit of metacognition is often appropriate. </p> <h3 id="bce39fbfe8964742af9e45be2d3752e8"> Conclusion <a href="#bce39fbfe8964742af9e45be2d3752e8" title="permalink">#</a> </h3> <p> How do you convince your manager or team mates to do things better? </p> <p> I don't know; I'm not a salesman, but in this essay, I've nonetheless tried to reflect on the question. I think it helps to consider what the other party gains from accepting a change, but I also think it's a waiting game. You have to be patient. </p> <p> As an economist, I could also say much about incentives, but this essay is already long enough as it is. Still, when you consider how your counterparts react to your suggestions, reflect on how they are incentivised. </p> <p> Even if you do everything right, make the best suggestions at the most opportune times, you may find yourself in a situation systemically rigged against doing the right thing. Ultimately, as <a href="https://martinfowler.com">Martin Fowler</a> quipped, <a href="https://wiki.c2.com/?ChangeYourOrganization">either change your organisation, or change your organisation</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Backwards compatibility as a profunctor https://blog.ploeh.dk/2021/12/13/backwards-compatibility-as-a-profunctor 2021-12-13T07:01:00+00:00 Mark Seemann <div id="post"> <p> <em>In order to keep backwards compatibility, you can weaken preconditions or strengthen postconditions.</em> </p> <p> Like the previous articles on <a href="/2021/11/29/postels-law-as-a-profunctor">Postel's law as a profunctor</a> and <a href="/2021/12/06/the-liskov-substitution-principle-as-a-profunctor">the Liskov Substitution Principle as a profunctor</a>, this article is part of a series titled <a href="/2018/03/05/some-design-patterns-as-universal-abstractions">Some design patterns as universal abstractions</a>. And like the previous articles, it's a bit of a stretch including the present article in that series, since <a href="https://en.wikipedia.org/wiki/Backward_compatibility">backwards compatibility</a> isn't a <a href="https://en.wikipedia.org/wiki/Software_design_pattern">design pattern</a>, but rather a software design principle or heuristic. I still think, however, that the article fits the spirit of the article series, if not the letter. </p> <p> Backwards compatibility is often (but not always) a desirable property of a system. Even in <a href="/2012/12/18/ZookeepersmustbecomeRangers">Zoo software, it pays to explicitly consider versioning</a>. In order to support <a href="https://en.wikipedia.org/wiki/Continuous_delivery">Continuous Delivery</a>, you must be able to evolve a system in such a way that it's always in a working state. </p> <p> When other systems depend on a system, it's important to maintain backwards compatibility. Evolve the system, but support legacy dependents as well. </p> <h3 id="eb3409db1d7f42109355387c2a72c4c4"> Adding new test code <a href="#eb3409db1d7f42109355387c2a72c4c4" title="permalink">#</a> </h3> <p> In <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, chapter 11 contains a subsection on adding new test code. Despite admonitions to the contrary, I often experience that programmers treat test code as a second-class citizen. They casually change test code in a more undisciplined way than they'd edit production code. Sometimes, that may be in order, but I wanted to show that you <em>can</em> approach the task of editing test code in a more disciplined way. After all, <a href="/2013/04/02/why-trust-tests">the more you edit tests, the less you can trust them</a>. </p> <p> After a preliminary discussion about adding entirely new test code, the book goes on to say: </p> <blockquote> <p> You can also append test cases to a parametrised test. If, for example, you have the test cases shown in listing 11.1, you can add another line of code, as shown in listing 11.2. That’s hardly dangerous. </p> <p> <strong>Listing 11.1</strong> A parametrised test method with three test cases. Listing 11.2 shows the updated code after I added a new test case. <em>(Restaurant/b789ef1/Restaurant.RestApi.Tests/ReservationsTests.cs)</em> </p> <p> <pre>[Theory] [InlineData(<span style="color:blue;">null</span>,&nbsp;<span style="color:#a31515;">&quot;j@example.net&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Jay&nbsp;Xerxes&quot;</span>,&nbsp;1)] [InlineData(<span style="color:#a31515;">&quot;not&nbsp;a&nbsp;date&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;w@example.edu&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Wk&nbsp;Hd&quot;</span>,&nbsp;8)] [InlineData(<span style="color:#a31515;">&quot;2023-11-30&nbsp;20:01&quot;</span>,&nbsp;<span style="color:blue;">null</span>,&nbsp;<span style="color:#a31515;">&quot;Thora&quot;</span>,&nbsp;19)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">PostInvalidReservation</span>(</pre> </p> <p> <strong>Listing 11.2</strong> A test method with a new test case appended, compared to listing 11.1. The line added is highlighted. <em>(Restaurant/745dbf5/Restaurant.RestApi.Tests/ReservationsTests.cs)</em> </p> <p> <pre>[Theory] [InlineData(<span style="color:blue;">null</span>,&nbsp;<span style="color:#a31515;">&quot;j@example.net&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Jay&nbsp;Xerxes&quot;</span>,&nbsp;1)] [InlineData(<span style="color:#a31515;">&quot;not&nbsp;a&nbsp;date&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;w@example.edu&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Wk&nbsp;Hd&quot;</span>,&nbsp;8)] [InlineData(<span style="color:#a31515;">&quot;2023-11-30&nbsp;20:01&quot;</span>,&nbsp;<span style="color:blue;">null</span>,&nbsp;<span style="color:#a31515;">&quot;Thora&quot;</span>,&nbsp;19)] <strong>[InlineData(<span style="color:#a31515;">&quot;2022-01-02&nbsp;12:10&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;3@example.org&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;3&nbsp;Beard&quot;</span>,&nbsp;0)]</strong> <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">PostInvalidReservation</span>(</pre> </p> <p> You can also add assertions to existing tests. Listing 11.3 shows a single assertion in a unit test, while listing 11.4 shows the same test after I added two more assertions. </p> <p> <strong>Listing 11.3</strong> A single assertion in a test method. Listing 11.4 shows the updated code after I added more assertions. <em>(Restaurant/36f8e0f/Restaurant.RestApi.Tests/ReservationsTests.cs)</em> </p> <p> <pre>Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;HttpStatusCode.InternalServerError, &nbsp;&nbsp;&nbsp;&nbsp;response.StatusCode);</pre> </p> <p> <strong>Listing 11.4</strong> Verification phase after I added two more assertions, compared to listing 11.3. The lines added are highlighted. <em>(Restaurant/0ab2792/Restaurant.RestApi.Tests/ReservationsTests.cs)</em> </p> <p> <pre>Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;HttpStatusCode.InternalServerError, &nbsp;&nbsp;&nbsp;&nbsp;response.StatusCode); <strong>Assert.NotNull(response.Content); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">content</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;response.Content.ReadAsStringAsync(); Assert.Contains( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;tables&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;content, &nbsp;&nbsp;&nbsp;&nbsp;StringComparison.OrdinalIgnoreCase);</strong></pre> </p> <p> These two examples are taken from a test case that verifies what happens if you try to overbook the restaurant. In listing 11.3, the test only verifies that the HTTP response is <code>500 Internal Server Error</code>. The two new assertions verify that the HTTP response includes a clue to what might be wrong, such as the message <code>No tables available</code>. </p> <p> I often run into programmers who’ve learned that a test method may only contain a single assertion; that having multiple assertions is called Assertion Roulette. I find that too simplistic. You can view appending new assertions as a strengthening of postconditions. With the assertion in listing 11.3 any <code>500 Internal Server Error</code> response would pass the test. That would include a 'real' error, such as a missing connection string. This could lead to false negatives, since a general error could go unnoticed. </p> <p> Adding more assertions strengthens the postconditions. Any old <code>500 Internal Server Error</code> will no longer do. The HTTP response must also come with content, and that content must, at least, contain the string <code>"tables"</code>. </p> <p> This strikes me as reminiscent of the <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov Substitution Principle</a>. There are many ways to express it, but in one variation, we say that subtypes may weaken preconditions and strengthen postconditions, but not the other way around. You can think of of subtyping as an ordering, and you can think of time in the same way, as illustrated by figure 11.1. Just like a subtype depends on its supertype, a point in time 'depends' on previous points in time. Going forward in time, you’re allowed to strengthen the postconditions of a system, just like a subtype is allowed to strengthen the postcondition of a supertype. </p> <p> <img src="/content/binary/type-hierarchy-and-time.png" alt="A type hierarchy forms a directed graph, as indicated by the arrow from subtype to supertype. Time, too, forms a directed graph, as indicated by the arrow from t2 to t1. Both present a way to order elements."> </p> <p> <strong>Figure 11.1</strong> A type hierarchy forms a directed graph, as indicated by the arrow from <em>subtype</em> to <em>supertype</em>. Time, too, forms a directed graph, as indicated by the arrow from <em>t<sub>2</sub></em> to <em>t<sub>1</sub></em>. Both present a way to order elements. </p> <p> Think of it another way, adding new tests or assertions is fine; deleting tests or assertions would weaken the guarantees of the system. You probably don’t want that; herein lie regression bugs and breaking changes. </p> </blockquote> <p> The book leaves it there, but I find it worthwhile to expand on that thought. </p> <h3 id="a1d529a2fbd04af4a9a2a08bc3c17bed"> Function evolution over time <a href="#a1d529a2fbd04af4a9a2a08bc3c17bed" title="permalink">#</a> </h3> <p> As in the previous articles about <em>x as a profunctor</em>, let's first view 'a system' as a function. As I've repeatedly suggested, <a href="/2018/01/22/function-isomorphisms">with sufficient imagination, every operation looks like a function</a>. Even an HTTP <code>POST</code> request, as suggested in the above test snippets, can be considered a function, albeit one with <a href="/2020/06/08/the-io-container">the IO effect</a>. </p> <p> You can <a href="/2021/11/22/functions-as-pipes">envision a function as a pipe</a>. In previous articles, I've drawn horizontal pipes, with data flowing from left to right, but we can also rotate them 90° and place them on a timeline: </p> <p> <img src="/content/binary/function-pipes-on-timeline.png" alt="Function pipes on a timeline."> </p> <p> As usually depicted in Western culture, time moves from left to right. In a stable system, functions don't change: The function at <em>t<sub>1</sub></em> is equal to the function at <em>t<sub>2</sub></em>. </p> <p> The function in the illustration takes values belonging to the set <em>a</em> as input and returns values belonging to the set <em>b</em> as output. A bit more formally, we can denote the function as having the type <code>a -&gt; b</code>. </p> <p> We can view the passing of time as a translation of the function <code>a -&gt; b</code> at <em>t<sub>1</sub></em> to <code>a -&gt; b</code> at <em>t<sub>2</sub></em>. If we just leave the function alone (as implied by the above figure), it corresponds to mapping the function with the identity function. </p> <p> Clients that rely on the function are calling it by supplying input values from the set <em>a</em>. In return, they receive values from the set <em>b</em>. As already discussed in the article about <a href="/2021/11/29/postels-law-as-a-profunctor">Postel's law as a profunctor</a>, we can illustrate such a fit between client and function as snugly fitting pipes: </p> <p> <img src="/content/binary/function-pipes-and-clients-on-timeline.png" alt="Function pipes and clients on a timeline."> </p> <p> As long as the clients keep supplying elements from <em>a</em> and expecting elements from <em>b</em> in return, the function remains compatible. </p> <p> If we have to change the function, which kind of change will preserve compatibility? </p> <p> We can make the function accept a wider set of input, and let it return narrower set of output: </p> <p> <img src="/content/binary/function-pipe-flanged-pipe-and-clients-on-timeline.png" alt="Function pipe, flanged pipe, and clients on a timeline."> </p> <p> This will not break any existing clients, because they'll keep calling the function with <em>a</em> input and expecting <em>b</em> output values. The drawing is similar to the drawings from the articles on <a href="/2021/11/29/postels-law-as-a-profunctor">Postel's law as a profunctor</a> and <a href="/2021/12/06/the-liskov-substitution-principle-as-a-profunctor">The Liskov Substitution Principle as a profunctor</a>. It seems reasonable to consider backwards compatibility in the same light. </p> <h3 id="29913e188d87465c897cfaf96b3de349"> Profunctor <a href="#29913e188d87465c897cfaf96b3de349" title="permalink">#</a> </h3> <p> Consider backwards compatible function evolution as a mapping of a function <code>a -&gt; b</code> at <em>t<sub>1</sub></em> to <code>a' -&gt; b'</code> at <em>t<sub>2</sub></em>. </p> <p> What rules should we institute for this mapping? </p> <p> In order for this translation to be backwards compatible, we must be able to translate the larger input set <code>a'</code> to <code>a</code>; that is: <code>a' -&gt; a</code>. That's the top flange in the above figure. </p> <p> Likewise, we must be able to translate the original output set <code>b</code> to the smaller <code>b'</code>: <code>b -&gt; b'</code>. That's the bottom nozzle in the above figure. </p> <p> Thus, armed with the two functions <code>a' -&gt; a</code> and <code>b -&gt; b'</code>, we can translate <code>a -&gt; b</code> at <em>t<sub>1</sub></em> to <code>a' -&gt; b'</code> at <em>t<sub>2</sub></em> in a way that preserves backwards compatibility. More formally: </p> <p> <pre>(a' -&gt; a) -&gt; (b -&gt; b') -&gt; (a -&gt; b) -&gt; (a' -&gt; b')</pre> </p> <p> This is exactly the definition of <code>dimap</code> for <a href="/2021/11/08/reader-as-a-profunctor">the Reader profunctor</a>! </p> <h3 id="f9fb3a037ed34eeeaea489cb45b830f6"> Arrow directions <a href="#f9fb3a037ed34eeeaea489cb45b830f6" title="permalink">#</a> </h3> <p> That's why I wrote as I did in <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. The direction of the arrows in the book's <em>figure 11.1</em> may seem counter-intuitive, but I had them point in that direction because that's how most readers are used to see supertypes and subtypes depicted. </p> <p> When thinking of concepts such as <a href="https://en.wikipedia.org/wiki/Robustness_principle">Postel's law</a>, it may be more intuitive to think of the <a href="/2021/11/01/profunctors">profunctor</a> as a mapping from a formal specification <code>a -&gt; b</code> to the more robust implementation <code>a' -&gt; b'</code>. That is, the arrow would point in the other direction. </p> <p> Likewise, when we think of <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">the Liskov Substitution Principle</a> as rule about how to lawfully derive subtypes from supertypes, again we have a mapping from the supertype <code>a -&gt; b</code> to the subtype <code>a' -&gt; b'</code>. Again, the arrow direction goes from supertype to subtype - that is, in the opposite direction from the book's <em>figure 11.1</em>. </p> <p> This now also better matches how we intuitively think about time, as flowing from left to right. The arrow, again, goes from <em>t<sub>1</sub></em> to <em>t<sub>2</sub></em>. </p> <p> Most of the time, the function doesn't change as time goes by. This corresponds to the mapping <code>dimap id id</code> - that is, applying the identity function to the mapping. </p> <h3 id="ff48c88ef49b438f8a0085c16ce11442"> Implications for tests <a href="#ff48c88ef49b438f8a0085c16ce11442" title="permalink">#</a> </h3> <p> Consider the test snippets shown at the start of the article. When you add test cases to an existing test, you increase the size of the input set. Granted, unit test inputs are only samples of the entire input set, but it's still clear that adding a test case increases the input set. Thus, we can view such an edit as a mapping <code>a -&gt; a'</code>, where <code>a ⊂ a'</code>. </p> <p> Likewise, when you add more assertions to an existing set of assertions, you add extra constraints. Adding an assertion implies that the test must pass <em>all</em> of the previous assertions, <em>as well as</em> the new one. That's a Boolean <em>and</em>, which implies a narrowing of the allowed result set (unless the new assertion is a <a href="/2019/10/14/tautological-assertion">tautological assertion</a>). Thus, we can view adding an assertion as a mapping <code>b -&gt; b'</code>, where <code>b' ⊂ b</code>. </p> <p> This is why it's okay to add more test cases, and more assertions, to an existing test, whereas you should be weary of the opposite: It may imply (or at least allow) a breaking change. </p> <h3 id="f8cfe2b42dff43a388b3cd5da9746f09"> Conclusion <a href="#f8cfe2b42dff43a388b3cd5da9746f09" title="permalink">#</a> </h3> <p> As <a href="https://michaelfeathers.silvrback.com/the-universality-of-postel-s-law">Michael Feathers observed</a>, Postel's law seems universal. That's one way to put it. </p> <p> Another way to view it is that Postel's law is a formulation of a kind of profunctor. And it certainly seems as though profunctors pop up here, there, and everywhere, once you start looking for that idea. </p> <p> We can think of the Liskov Substitution Principle as a profunctor, and backwards compatibility as well. It seems reasonable enough: In order to stay backwards compatible, a function can become more tolerant of input, or more conservative in what it returns. Put another way: Contravariant in input, and covariant in output. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. The Liskov Substitution Principle as a profunctor https://blog.ploeh.dk/2021/12/06/the-liskov-substitution-principle-as-a-profunctor 2021-12-06T06:52:00+00:00 Mark Seemann <div id="post"> <p> <em>With a realistic example in C#.</em> </p> <p> Like the previous article on <a href="/2021/11/29/postels-law-as-a-profunctor">Postel's law as a profunctor</a>, this article is part of a series titled <a href="/2018/03/05/some-design-patterns-as-universal-abstractions">Some design patterns as universal abstractions</a>. And like the previous article, it's a bit of a stretch to include the present article in that series, since the <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov Substitution Principle</a> (LSP) isn't a <a href="https://en.wikipedia.org/wiki/Software_design_pattern">design pattern</a>, but rather a software design principle or heuristic. I still think, however, that the article fits the spirit of the article series, if not the letter. </p> <p> As was also the case for the previous article, I don't claim that any of this is new. <a href="https://twitter.com/runarorama/status/1425946258234032130">Michael Feathers and Rúnar Bjarnason blazed that trail long before me</a>. </p> <h3 id="95f8226160af4ba7a62e5d8f7d4da5c5"> LSP distilled <a href="#95f8226160af4ba7a62e5d8f7d4da5c5" title="permalink">#</a> </h3> <p> In more or less natural language, the LSP states that subtypes must preserve correctness. A subtype isn't allowed to change behaviour in such a way that client code breaks. </p> <p> Note that subtypes <em>are</em> allowed to change behaviour. That's often the point of subtyping. By providing a subtype, you can change the behaviour of a system. You can, for example, override how messages are sent, so that an SMS becomes a Slack notification or a Tweet. </p> <p> If client code 'originally' supplied correct input for sending an SMS, this input should also be valid for posting a Tweet. </p> <p> Specifically (paraphrasing <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">the Wikipedia entry as of early November 2021</a>): </p> <p> <ul> <li>Subtypes must be contravariant in input</li> <li>Subtypes must be covariant in output</li> <li>Preconditions must not be strengthened in the subtype</li> <li>Postconditions must not be weakened in the subtype</li> </ul> </p> <p> There's a bit more, but in this article, I'll focus on those rules. The first two we already know. Since <a href="/2021/11/08/reader-as-a-profunctor">any function is already a profunctor</a>, we know that functions are contravariant in input and covariant in output. </p> <p> The LSP, however, isn't a rule about a single function. Rather, it's a rule about a family of functions. Think about a function <code>a -&gt; b</code> <a href="/2021/11/22/functions-as-pipes">as a pipe</a>. You can replace the pipe segment with another pipe segment that has exactly the same shape, but replacing it with a flanged pipe also works, as long as the input flange is wider, and the nozzle narrower than the original pipe shape. </p> <p> <img src="/content/binary/lsp-pipes.png" alt="The Liskov Substitution Principle illustrated with flanged pipes."> </p> <p> On the other hand, if you narrow the pipe at the input and widen it at the output, spillage will happen. That's essentially what the LSP states: The upper, green, flanged pipe is a good replacement for the supertype (the blue pipe in the middle), while the lower, orange, flanged pipe is not useful. </p> <p> The previous article already described that visual metaphor when it comes to co- and contravariance, so this article will focus on pre- and postconditions. My conjecture is that this is just another take on co- and contravariance. </p> <h3 id="73b14971495b4701a322f95ff3f332a0"> Supertype example <a href="#73b14971495b4701a322f95ff3f332a0" title="permalink">#</a> </h3> <p> When encountering statements about subtypes and supertypes, most people tend to think about object inheritance, but that's just one example. As I've <a href="/2021/10/25/functor-variance-compared-to-cs-notion-of-variance">previously outlined</a>, anything that can 'act as' something else is a subtype of that something else. Specifically, an interface implementation is a subtype of the interface, and the interface itself the supertype. </p> <p> Consider, as a supertype example, this interface from my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReservationsRepository</span> { &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Create</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;Reservation?&gt;&nbsp;<span style="color:#74531f;">ReadReservation</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Guid&nbsp;<span style="color:#1f377f;">id</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Update</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Delete</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Guid&nbsp;<span style="color:#1f377f;">id</span>); }</pre> </p> <p> Specifically, in this article, I'll focus exclusively on the <code>ReadReservations</code> method. You can imagine that there's an interface with only that method, or that when subtyping the interface in the following, we vary only that method and keep everything else fixed. </p> <p> What might be the pre- and postconditions of the <code>ReadReservations</code> method? </p> <h3 id="18ffff3d0ba7474086053e283d3bd77b"> ReadReservations preconditions <a href="#18ffff3d0ba7474086053e283d3bd77b" title="permalink">#</a> </h3> <p> The most basic kind of precondition is captured by the parameter types. In order to be able to call the method, you must supply an <code>int</code> and two <code>DateTime</code> instances. You can't omit any of them or replace one of the <code>DateTime</code> values with a <code>Guid</code>. In a statically typed language, this is obvious, and the compiler will take care of that. </p> <p> Both <code>int</code> and <code>DateTime</code> are value types (<code>struct</code>s), so they can't be null. Had one of the parameters been a reference type, it'd be appropriate to consider whether or not null constitutes valid input. </p> <p> So far, we've only discussed static types. Of course a subtype must satisfy the compiler, but what other pre-conditions might be implied by <code>ReadReservations</code>? </p> <p> The purpose of the method is to enable client code to query a data store and retrieve the reservations for a particular restaurant and in a particular time interval. </p> <p> Is any <code>restaurantId</code> acceptable? <code>1</code>? <code>0</code>? <code>-235</code>? </p> <p> It's probably a distraction that the restaurant ID is even an <code>int</code>. After all, you don't add IDs together, or multiply one with another one. That an ID is an integer is really just a leaky implementation detail - databases like it best when IDs are integers. I should actually have defined the restaurant ID as an opaque object with <a href="https://martinfowler.com/bliki/ValueObject.html">Value Object</a> semantics, but I didn't (like other humans, I'm imperfect and lazy). The bottom line is that any number is as good as any other number. No precondition there. </p> <p> What about the two <code>DateTime</code> parameters? Are <code>DateTime.MinValue</code> or <code>DateTime.MaxValue</code> valid values? Probably: If you'd like to retrieve all reservations in the past, you could ask for <code>DateTime.MinValue</code> as <code>min</code> and <code>DateTime.Now</code> as <code>max</code>. On the other hand, it'd be reasonable to require that <code>min</code> should be less than (or equal to?) <code>max</code>. That sounds like a proper precondition, and one that's difficult to express as a type. </p> <p> We may also consider it a precondition that the object that implements the <code>ReadReservations</code> method is properly initialised, but I'll take that as a given. Making sure of that is the responsibility of the constructor, not the <code>ReadReservations</code> method. </p> <p> To summarise, apart from the types and other things handled by the compiler, there's only one additional pre-condition: that <code>min</code> must be less than <code>max</code>. </p> <p> Are there any postconditions? </p> <h3 id="e1588e7f3cb7406f8a15b286edfd570e"> ReadReservations postconditions <a href="#e1588e7f3cb7406f8a15b286edfd570e" title="permalink">#</a> </h3> <p> The code base for the book obeys <a href="https://en.wikipedia.org/wiki/Command%E2%80%93query_separation">Command-Query Separation</a>. Since <code>ReadReservations</code> returns data, it must be a Query. Thus, we can assume that calling it isn't supposed to change state. Thus, postconditions can only be statements about the return value. </p> <p> Again, static typing takes care of the most fundamental postconditions. An implementation can't return a <code>double</code> or an <code>UriBuilder</code>. It must be a <code>Task</code>, and that task must compute an <code>IReadOnlyCollection&lt;Reservation&gt;</code>. </p> <p> Why <code>IReadOnlyCollection</code>, by the way? That's my attempt at describing a particular postcondition as a type. </p> <p> The <a href="https://docs.microsoft.com/dotnet/api/system.collections.generic.ireadonlycollection-1">IReadOnlyCollection&lt;T&gt;</a> interface is a restriction of <code>IEnumerable&lt;T&gt;</code> that adds a <code>Count</code>. By adding the <code>Count</code> property, the interface strongly suggests that the collection is finite. </p> <p> <code>IEnumerable&lt;T&gt;</code> implementations can be infinite sequences. These can be useful as functional alternatives to infinite loops, but are clearly not appropriate when retrieving reservations from a database. </p> <p> The use of <code>IReadOnlyCollection</code> tells us about a postcondition: The collection of reservations is finite. This is, however, captured by the type. Any valid implementation of the interface ought to make that guarantee. </p> <p> Is there anything else? Is it okay if the collection is empty? Yes, that could easily happen, if you have no reservations in the requested interval. </p> <p> What else? Not much comes to mind, only that we'd expect the collection to be 'stable'. Technically, you could implement the <code>GetEnumerator</code> method so that it generates <code>Count</code> random <code>Reservation</code> objects every time you enumerate it, but none of the built-in implementations do that; that's quite a low bar, as postconditions go. </p> <p> To summarise the postconditions: None, apart from a well-behaved implementation of <code>IReadOnlyCollection&lt;Reservation&gt;</code>. </p> <h3 id="1b02cb07547e405b86e2d42d889b7bef"> SQL implementation <a href="#1b02cb07547e405b86e2d42d889b7bef" title="permalink">#</a> </h3> <p> According to the LSP, a subtype should be allowed to weaken preconditions. Keep in mind that I consider an interface implementation a subtype, so every implementation of <code>ReadReservations</code> constitutes a subtype. Consider the SQL Server-based implementation: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">result</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;List&lt;Reservation&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">using</span>&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">conn</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;SqlConnection(ConnectionString); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">using</span>&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">cmd</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;SqlCommand(readByRangeSql,&nbsp;conn); &nbsp;&nbsp;&nbsp;&nbsp;cmd.Parameters.AddWithValue(<span style="color:#a31515;">&quot;@RestaurantId&quot;</span>,&nbsp;restaurantId); &nbsp;&nbsp;&nbsp;&nbsp;cmd.Parameters.AddWithValue(<span style="color:#a31515;">&quot;@Min&quot;</span>,&nbsp;min); &nbsp;&nbsp;&nbsp;&nbsp;cmd.Parameters.AddWithValue(<span style="color:#a31515;">&quot;@Max&quot;</span>,&nbsp;max); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;conn.OpenAsync().ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">using</span>&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">rdr</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;cmd.ExecuteReaderAsync().ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">while</span>&nbsp;(<span style="color:blue;">await</span>&nbsp;rdr.ReadAsync().ConfigureAwait(<span style="color:blue;">false</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.Add(ReadReservationRow(rdr)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;result.AsReadOnly(); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">const</span>&nbsp;<span style="color:blue;">string</span>&nbsp;readByRangeSql&nbsp;=&nbsp;<span style="color:maroon;">@&quot; &nbsp;&nbsp;&nbsp;&nbsp;SELECT&nbsp;[PublicId],&nbsp;[At],&nbsp;[Name],&nbsp;[Email],&nbsp;[Quantity] &nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;[dbo].[Reservations] &nbsp;&nbsp;&nbsp;&nbsp;WHERE&nbsp;[RestaurantId]&nbsp;=&nbsp;@RestaurantId&nbsp;AND &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Min&nbsp;&lt;=&nbsp;[At]&nbsp;AND&nbsp;[At]&nbsp;&lt;=&nbsp;@Max&quot;</span>;</pre> </p> <p> This implementation actually doesn't enforce the precondition that <code>min</code> ought to be less than <code>max</code>. It doesn't have to, since the code will run even if that's not the case - the result set, if <code>min</code> is greater than <code>max</code>, will always be empty. </p> <p> While perhaps not useful, weakening this precondition doesn't adversely affect well-behaved clients, and buggy clients are always going to receive empty results. If this implementation also fulfils all postconditions, it's already LSP-compliant. </p> <p> Still, could it weaken preconditions even more, or in a different way? </p> <h3 id="a7427e15a9614179939911f25959e093"> Weakening of preconditions <a href="#a7427e15a9614179939911f25959e093" title="permalink">#</a> </h3> <p> As <a href="https://en.wikipedia.org/wiki/Robustness_principle">Postel's law</a> suggests, a method should be <em>liberal in what it accepts</em>. If it understands 'what the caller meant', it should perform the desired operation instead of insisting on the letter of the law. </p> <p> Imagine that you receive a call where <code>min</code> is midnight June 6 and <code>max</code> is midnight June 5. While wrong, what do you think that the caller 'meant'? </p> <p> The caller probably wanted to retrieve the reservations for June 5. </p> <p> You could weaken that precondition by swapping back <code>min</code> and <code>max</code> if you detect that they've been swapped. </p> <p> Let's assume, for the sake of argument, that we make the above <code>ReadReservations</code> implementation <code>virtual</code>. This enables us to inherit from <code>SqlReservationsRepository</code> and override the method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(max&nbsp;&lt;&nbsp;min) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">base</span>.ReadReservations(restaurantId,&nbsp;max,&nbsp;min); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">base</span>.ReadReservations(restaurantId,&nbsp;min,&nbsp;max); }</pre> </p> <p> While this weakens preconditions, it breaks no existing clients because they all 'know' that they must pass the lesser value before the greater value. </p> <h3 id="1e73ce9509ed4004a9c26c23ea186e7c"> Strengthening of postconditions <a href="#1e73ce9509ed4004a9c26c23ea186e7c" title="permalink">#</a> </h3> <p> Postel's law also suggests that a method should be <em>conservative in what it sends</em>. What could that mean? </p> <p> In the case of <code>ReadReservations</code>, you may notice that the result set isn't explicitly sorted. Perhaps we'd like to also sort it on the date and time: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">query</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min&nbsp;&lt;&nbsp;max&nbsp;? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">base</span>.ReadReservations(restaurantId,&nbsp;min,&nbsp;max)&nbsp;: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">base</span>.ReadReservations(restaurantId,&nbsp;max,&nbsp;min); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">reservations</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;query.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;reservations.OrderBy(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;r.At).ToList(); }</pre> </p> <p> This implementation retains the weakened precondition from before, but now it also explicitly sorts the reservations on <code>At</code>. </p> <p> Since no client code relies on sorting, this breaks no existing clients. </p> <p> While the behaviour changes, it does so in a way that doesn't violate the original contract. </p> <h3 id="e254e40ed8634bdeb144ac4f6711409c"> Profunctor <a href="#e254e40ed8634bdeb144ac4f6711409c" title="permalink">#</a> </h3> <p> While we've used terms such as <em>weaken preconditions</em> and <em>strengthen postconditions</em>, doesn't this look an awful lot like co- and contravariance? </p> <p> I think it does, so let's rewrite the above implementation using the <a href="/2021/11/08/reader-as-a-profunctor">Reader profunctor</a>. </p> <p> First, we'll need to express the original method in the shape of a function like <code>a -&gt; b</code> - that is: a function that takes a single input and returns a single output. While <code>ReadReservations</code> return a single value (a <code>Task</code>), it takes three input arguments. To make it fit the <code>a -&gt; b</code> mould, we have to <a href="/2018/01/29/argument-list-isomorphisms">convert those three parameters to a Parameter Object</a>. </p> <p> This enables us to write the original implementation as a function: </p> <p> <pre>Func&lt;QueryParameters,&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&gt;&nbsp;<span style="color:#1f377f;">imp</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">q</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">base</span>.ReadReservations(q.RestaurantId,&nbsp;q.Min,&nbsp;q.Max);</pre> </p> <p> If we didn't want to weaken any preconditions or strengthen any postconditions, we could simply call <code>imp</code> and return its output. </p> <p> The above weakened precondition can be expressed like this: </p> <p> <pre>Func&lt;QueryParameters,&nbsp;QueryParameters&gt;&nbsp;<span style="color:#1f377f;">pre</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">q</span>&nbsp;=&gt;&nbsp;q.Min&nbsp;&lt;&nbsp;q.Max&nbsp;? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;QueryParameters(q.RestaurantId,&nbsp;q.Min,&nbsp;q.Max)&nbsp;: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;QueryParameters(q.RestaurantId,&nbsp;q.Max,&nbsp;q.Min);</pre> </p> <p> Notice that this is a function from <code>QueryParameters</code> to <code>QueryParameters</code>. As above, it simply swaps <code>Min</code> and <code>Max</code> if required. </p> <p> Likewise, we can express the strengthened postcondition as a function: </p> <p> <pre>Func&lt;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;,&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&gt;&nbsp;<span style="color:#1f377f;">post</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;t.Select(<span style="color:#1f377f;">rs</span>&nbsp;=&gt;&nbsp;rs.OrderBy(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;r.At).ToReadOnly());</pre> </p> <p> The <code>Select</code> method exists because <code>Task</code> forms an <a href="/2018/09/24/asynchronous-functors">asynchronous functor</a>. </p> <p> It's now possible to compose <code>imp</code> with <code>pre</code> and <code>post</code> using <code>DiMap</code>: </p> <p> <pre>Func&lt;QueryParameters,&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&gt;&nbsp;<span style="color:#1f377f;">composition</span>&nbsp;=&nbsp;imp.DiMap(pre,&nbsp;post);</pre> </p> <p> You can now call <code>composition</code> with the original arguments: </p> <p> <pre>composition(<span style="color:blue;">new</span>&nbsp;QueryParameters(restaurantId,&nbsp;min,&nbsp;max))</pre> </p> <p> The output of such a function call is entirely equivalent to the above, subtyped <code>ReadReservations</code> implementation. </p> <p> In case you've forgotten, the presence of a lawful <code>DiMap</code> function is what makes something a profunctor. We <a href="/2021/11/08/reader-as-a-profunctor">already knew that functions are profunctors</a>, but now we've also seen that we can use this knowledge to weaken preconditions and strengthen postconditions. </p> <p> It seems reasonable to conjecture that the LSP actually describes a profunctor. </p> <p> It seems to me that the profunctor composition involved with the LSP always takes the specialised form where, for a function <code>a -&gt; b</code>, the preprocessor (the contravariant mapping) always takes the form <code>a -&gt; a</code>, and the postprocessor (the covariant mapping) always takes the form <code>b -&gt; b</code>. This is because polymorphism must preserve the shape of the original function (<code>a -&gt; b</code>). </p> <h3 id="bca3373857e246a280bce24c83f2e8ac"> Conclusion <a href="#bca3373857e246a280bce24c83f2e8ac" title="permalink">#</a> </h3> <p> We already know that something contravariant in input and covariant in output is a profunctor candidate, but the Liskov Substitution Principle is usually expressed in terms of pre- and postconditions. Subtypes may weaken preconditions and strengthen postconditions, but not the other way around. </p> <p> Evidence suggests that you can phrase these rules as a profunctor specialisation. </p> <p> <strong>Next:</strong> <a href="/2021/12/13/backwards-compatibility-as-a-profunctor">Backwards compatibility as a profunctor</a>. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="79c6999370fd4c1f955c6f2c243d23b0"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <blockquote> It seems to me that the profunctor composition involved with the LSP always takes the specialised form where, for a function <code>a -&gt; b</code>, the preprocessor (the contravariant mapping) always takes the form <code>a -&gt; a</code>, and the postprocessor (the covariant mapping) always takes the form <code>b -&gt; b</code>. This is because polymorphism must preserve the shape of the original function (<code>a -&gt; b</code>). </blockquote> <p> I think this depends on the language and your perspective on subtype polymorphism. In Java, a subclass <code>Y</code> of a superclass <code>X</code> can override a method <code>m</code> on <code>X</code> that has return type <code>b</code> with a method on <code>Y</code> that has return type <code>c</code> provided <code>c</code> is a subtype of <code>b</code>. To be clear, I am not saying that the instance returned from <code>Y::m</code> can have runtime-type <code>c</code>, though that is also true. I am saying that the compile-time return type of <code>Y::m</code> can be <code>c</code>. </p> <p> With this in mind, I am willing to argue that the postprocessor can take the form <code>b -&gt; c</code> provided <code>c</code> is a subtype of <code>b</code>. As the programmer, that is how I think of <code>Y::m</code>. And yet, if someone has a instance of <code>Y</code> with compile-time type <code>X</code>, then calling <code>m</code> returns something with compile-time type <code>b</code> by composing my <code>b -&gt; c</code> function with the natural <code>c -&gt; b</code> function from subtype polymorphism to get the <code>b -&gt; b</code> function that you suggested is required. </p> </div> <div class="comment-date">2021-12-10 05:28 UTC</div> </div> <div class="comment" id="c4279163948e4fda98899fa54a6cfc16"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tyson, thank you for writing. Yes, true, that nuance may exist. This implies that the LSP is recursive, which really isn't surprising. </p> <p> A function <code>a -&gt; b</code> may be defined for types <code>a</code> and <code>b</code>, where both are, themselves, polymorphic. So, if <code>a</code> is <a href="https://docs.microsoft.com/dotnet/api/system.httpstyleuriparser">HttpStyleUriParser</a> and <code>b</code> is <a href="https://docs.microsoft.com/dotnet/api/system.reflection.memberinfo">MemberInfo</a>, we'd have a function <code>Func&lt;HttpStyleUriParser, MemberInfo&gt;</code> (or <code>HttpStyleUriParser -&gt; MemberInfo</code> if we want to stick with an ML-style type signature - we can imagine that it's an <a href="https://fsharp.org">F#</a> function). </p> <p> If <code>Func&lt;HttpStyleUriParser, MemberInfo&gt;</code> is our polymorphic target signature, according to <a href="/2021/10/25/functor-variance-compared-to-cs-notion-of-variance">C# co- and contravariance</a>, we're allowed to vary both input and output. We can, for example, widen the input type to <a href="https://docs.microsoft.com/dotnet/api/system.uriparser">UriParser</a> and restrict the output type to <a href="https://docs.microsoft.com/dotnet/api/system.type">Type</a>. Thus, a <code>specific</code> function of the type <code>Func&lt;UriParser, Type&gt;</code> is compatible with a general function of the type <code>Func&lt;HttpStyleUriParser, MemberInfo&gt;</code>: </p> <p> <pre>Func&lt;HttpStyleUriParser,&nbsp;MemberInfo&gt;&nbsp;<span style="color:#1f377f;">general</span>&nbsp;=&nbsp;specific;</pre> </p> <p> Thus, you're correct that both pre- and postprocessor may take the form <code>a' -> a</code> and <code>b -> b'</code>, where <code>a'</code> is a supertype of <code>a</code>, and <code>b</code> is a supertype of <code>b'</code>. This is true for C# function delegates, since <a href="/2021/10/25/functor-variance-compared-to-cs-notion-of-variance">they're defined with the <code>in</code> and <code>out</code> keywords</a>. You can put <code>in</code> and <code>out</code> on your own interface definitions as well, but most people don't bother (I rarely do, either). </p> <p> As with all practical recursion you need base cases to stop the recursion. While you can define polymorphic functions (or classes) where input parameters and return types are themselves polymorphic, etc., these should still obey the LSP. </p> </div> <div class="comment-date">2021-12-14 07:12 UTC</div> </div> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Postel's law as a profunctor https://blog.ploeh.dk/2021/11/29/postels-law-as-a-profunctor 2021-11-29T07:10:00+00:00 Mark Seemann <div id="post"> <p> <em>When viewing inputs and outputs as sets, Postel's law looks like a profunctor.</em> </p> <p> This article is part of a series titled <a href="/2018/03/05/some-design-patterns-as-universal-abstractions">Some design patterns as universal abstractions</a>. Including the present article in that series is a bit of a stretch, since <a href="https://en.wikipedia.org/wiki/Robustness_principle">Postel's law</a> isn't really a <a href="https://en.wikipedia.org/wiki/Software_design_pattern">design pattern</a>, but rather a software design principle or heuristic. I still think, however, that the article fits the spirit of the article series, if not the letter. </p> <p> This article is heavily inspired by <a href="https://www.r7krecon.com/">Michael Feathers'</a> article <a href="https://michaelfeathers.silvrback.com/the-universality-of-postel-s-law">The Universality of Postel's Law</a>, in which he writes: </p> <blockquote> <p> [Postel's law] has been paraphrased over the years as “Be liberal in what you accept, and conservative in what you send” and for people who are mathematically inclined: “be contravariant in your inputs and covariant in your outputs.” </p> <footer><cite><a href="https://michaelfeathers.silvrback.com/the-universality-of-postel-s-law">Michael Feathers</a></cite></footer> </blockquote> <p> A thing contravariant in input and covariant in output sounds like a <a href="/2021/11/01/profunctors">profunctor</a>, but why does Michael Feathers write that about Postel's law? </p> <p> In this article, I'll try to explain. </p> <h3 id="31fb7a0153d24cd9bdc5d7f467488726"> Perfect fit <a href="#31fb7a0153d24cd9bdc5d7f467488726" title="permalink">#</a> </h3> <p> Postel's law is a statement about functions, methods, procedures, or whatever else you'd like to call them. As I've previously outlined, with sufficient squinting, <a href="/2018/01/22/function-isomorphisms">we can think about methods and other operations as functions</a>, so in this article I'll focus on functions. </p> <p> Functions don't stand alone. Functions have callers. Some other entity, usually <em>client code</em>, passes some input data to the function, which then performs its work and returns output data. When viewed with a set-based perspective, we can <a href="/2021/11/22/functions-as-pipes">depict a function as a pipe</a>: </p> <p> <img src="/content/binary/horizontal-pipe.png" alt="Horizontal pipe."> </p> <p> Client code often use the output of one function as input for another: </p> <p> <pre>Int3&nbsp;<span style="color:#1f377f;">isEven</span>&nbsp;=&nbsp;EncodeEven(number); Int3&nbsp;<span style="color:#1f377f;">decremented</span>&nbsp;=&nbsp;Decrement(isEven);</pre> </p> <p> Even though this code example uses an explicit intermediary variable (<code>isEven</code>), it's equivalent to function composition: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">composition</span>&nbsp;=&nbsp;EncodeEven.Compose(Decrement);</pre> </p> <p> where <code>Compose</code> can be implemented as: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;A,&nbsp;C&gt;&nbsp;<span style="color:#74531f;">Compose</span>&lt;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">B</span>,&nbsp;<span style="color:#2b91af;">C</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">f</span>,&nbsp;Func&lt;B,&nbsp;C&gt;&nbsp;<span style="color:#1f377f;">g</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(f(x)); }</pre> </p> <p> Such a composition we can depict by appending one pipe after another: </p> <p> <img src="/content/binary/two-composed-horizontal-pipes.png" alt="Two horizontal pipes composed one after the other."> </p> <p> This works, but is brittle. It's a close fit. The output set of the first function has to exactly fit the input set of the second function. What happens if the pipes don't perfectly align? </p> <h3 id="8e059f4a27d4496887a7b35399dbdcc1"> Misalignment <a href="#8e059f4a27d4496887a7b35399dbdcc1" title="permalink">#</a> </h3> <p> Functions compose when they fit perfectly, but in the real world, that's rarely the case. For example, it may turn out that <code>Decrement</code> is defined like this: </p> <p> <pre><span style="color:blue;">static</span>&nbsp;Int3&nbsp;<span style="color:#74531f;">Decrement</span>(Int3&nbsp;<span style="color:#1f377f;">i</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(i&nbsp;==&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentOutOfRangeException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(i), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;Can&#39;t&nbsp;decrement&nbsp;0.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;i&nbsp;-&nbsp;(Int3)1; }</pre> </p> <p> This function is undefined for <code>0</code>. If we wanted to peek at the set diagram 'inside' the pipe, we might depict the function like this: </p> <p> <img src="/content/binary/partial-decrement-set-diagram.png" alt="Decrement function set diagram."> </p> <p> In a sense, it's still a mapping from <a href="/2021/11/22/functions-as-pipes">our hypothetical 3-bit integer</a> to 3-bit integer, but it's a partial function. </p> <p> Another way to depict the mapping, however, is to constrain the <a href="https://en.wikipedia.org/wiki/Domain_of_a_function">domain</a> to <code>[1..7]</code>, and narrow the <a href="https://en.wikipedia.org/wiki/Codomain">codomain</a> to the function's <a href="https://en.wikipedia.org/wiki/Image_(mathematics)">image</a>, producing a <a href="https://en.wikipedia.org/wiki/Bijection">bijection</a>: </p> <p> <img src="/content/binary/total-decrement-set-diagram.png" alt="Total decrement function set diagram."> </p> <p> Such sets are a little harder to express in code, because how do you represent a set with seven elements? Often, you'd stick with an implementation like the above <code>Decrement</code> function. </p> <p> This turns out to be unfortunate, however, because <code>EncodeEven</code> is defined like this: </p> <p> <pre><span style="color:blue;">static</span>&nbsp;Int3&nbsp;<span style="color:#74531f;">EncodeEven</span>(Int3&nbsp;<span style="color:#1f377f;">i</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;i.IsEven&nbsp;?&nbsp;(Int3)1&nbsp;:&nbsp;(Int3)0; }</pre> </p> <p> As a set diagram, we might depict it like this: </p> <p> <img src="/content/binary/encode-even-set-diagram.png" alt="Set diagram for the EncodeEven function."> </p> <p> It turns out that half the inputs into the above composition don't work! It's almost as though the pipes are misaligned: </p> <p> <img src="/content/binary/misaligned-pipes.png" alt="Misaligned pipes."> </p> <p> This can easily happen, also in the real world: </p> <p> <img src="/content/binary/misaligned-drain-pipes.jpg" alt="Misaligned drain pipes."> </p> <p> This is also why Michael Feathers writes: </p> <blockquote> <p> We can see Postel in the physical world too. Every time you see a PVC pipe with a flanged end, you’re seeing something that serves as a decent visual metaphor for Postel’s Law. Those pipes fit well together because one end is more accepting. </p> <footer><cite><a href="https://michaelfeathers.silvrback.com/the-universality-of-postel-s-law">Michael Feathers</a></cite></footer> </blockquote> <p> In other words, there's nothing new in any of the above. I've just been supplying the illustrations. </p> <h3 id="fc4420f7ca184f7ca90224ace0db59c3"> Flanges <a href="#fc4420f7ca184f7ca90224ace0db59c3" title="permalink">#</a> </h3> <p> How should we interpret the idea of <em>flanges?</em> How do we illustrate them? Here's a way: </p> <p> <img src="/content/binary/flanged-pipe.png" alt="Flanged pipe."> </p> <p> Given our set-based interpretation of things, how should we interpret a flange? Let's isolate one of them. It doesn't matter which one, but lets consider the left flange. If we attempt to make it transparent, we could also draw it like this: </p> <p> <img src="/content/binary/transparent-flange.png" alt="Transparent flange."> </p> <p> What does that look like? It looks like a mapping from one set to another. </p> <p> The left-hand set is slightly larger than the right-hand set, but the illustration includes neither the elements of each set nor the arrows that connect them. </p> <p> If we think of the 'original' function as a function from the set <em>A</em> to the set <em>B</em> we can also write it in pseudo-code as <code>A -&gt; B</code>. In <a href="https://www.haskell.org">Haskell</a> you'd exactly write <code>A -&gt; B</code> if <code>A</code> and <code>B</code> were two concrete types. Polymorphically, though, you'd write any function as <code>a -&gt; b</code>, or in C# as <code>Func&lt;A, B&gt;</code>. </p> <p> Let's think of any function <code>a -&gt; b</code> as the 'perfect fit' case. While such a function composes with, say, a function <code>b -&gt; c</code>, the composition is brittle. It can easily become misaligned. </p> <p> How do we add flanges to the function <code>a -&gt; b</code>? </p> <p> As the above illustration of the flange implies, we can think of the flange as another function. Perhaps we should call the slightly larger set to the left <code>a<sup>+</sup></code> (since it's 'like' <code>a</code>, just larger - that is, more liberal). With that nomenclature, the flange would be a function <code>a<sup>+</sup> -&gt; a</code>. </p> <p> Likewise, the right flange would be a function <code>b -&gt; b<sup>-</sup></code>. Here, I've called the narrower set of the flange <code>b<sup>-</sup></code> because it's smaller (more conservative) than <code>b</code>. </p> <p> Thus, the flanged pipe is just the composition of these three functions: <code>a<sup>+</sup> -&gt; a</code>, <code>a -&gt; b</code>, and <code>b -&gt; b<sup>-</sup></code>: </p> <p> <img src="/content/binary/flange-composition.png" alt="Flange composition."> </p> <p> That's exactly how <code>dimap</code> is defined in Haskell: </p> <p> <code>dimap ab cd bc = cd . bc . ab</code> </p> <p> The implementation code uses other letters, and recall that Haskell is typically read from right to left. As its name implies, <code>ab</code> is a function <code>a -&gt; b</code>, <code>bc</code> is a function <code>b -&gt; c</code>, and <code>cd</code> is a function <code>c -&gt; d</code>. </p> <p> In other words, Postel's law is a description of <a href="/2021/11/08/reader-as-a-profunctor">the Reader profunctor</a>, or, as Michael Feathers put it: <em>Be contravariant in your inputs and covariant in your outputs.</em> </p> <h3 id="2886607b42c14f8484ff36a41d339549"> Conclusion <a href="#2886607b42c14f8484ff36a41d339549" title="permalink">#</a> </h3> <p> Postel's law is a useful design principle to keep in mind. Intuitively, it makes sense to think of it as making sure that pipes are flanged. The bigger the receiving flange is, and the smaller the nozzle is, the easier it is to compose the flanged pipe with other (flanged) pipes. </p> <p> Using mostly visual metaphor, this article demonstrates that this is equivalent with being contravariant in input and covariant in output, and thus that the principle describes a profunctor. </p> <p> Postel's law, however, isn't the only design principle describing a profunctor. </p> <p> <strong>Next:</strong> <a href="/2021/12/06/the-liskov-substitution-principle-as-a-profunctor">The Liskov Substitution Principle as a profunctor</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Functions as pipes https://blog.ploeh.dk/2021/11/22/functions-as-pipes 2021-11-22T06:30:00+00:00 Mark Seemann <div id="post"> <p> <em>A visual metaphor.</em> </p> <p> A recent article on <a href="/2021/11/15/types-as-sets">types as sets</a> briefly touched on functions as sets. For example, you can think of Boolean negation as a set of two arrows: </p> <p> <img src="/content/binary/not-function-set-diagram.png" alt="Boolean negation set diagram."> </p> <p> Here the arrows stay within the set, because the function is a function from the set of Boolean values to the set of Boolean values. </p> <p> In general, however, functions aren't always <a href="https://en.wikipedia.org/wiki/Endomorphism">endomorphisms</a>. They often map one set of values to another set. How can we think of this as sets? </p> <p> As was also the case with the article on types as sets, I'd like to point out that this article isn't necessarily mathematically rigorous. I'm neither a computer scientist nor a mathematician, and while I try to be as correct as possible, some hand-waving may occur. My purpose with this article isn't to prove a mathematical theorem, but rather to suggest what I, myself, find to be a useful metaphor. </p> <h3 id="ce1ac3b7b2bd49b1a7bf60591606017e"> Boolean negation visualised with domain and codomain <a href="#ce1ac3b7b2bd49b1a7bf60591606017e" title="permalink">#</a> </h3> <p> Instead of visualising Boolean negation within a single set, we can also visualise it as a mapping of elements from an input set (the <em>domain</em>) to an output set (the <em>codomain</em>): </p> <p> <img src="/content/binary/not-function-from-domain-to-codomain.png" alt="Boolean negation illustrated as arrows from the set on the left to the set on the right."> </p> <p> In this figure, the <a href="https://en.wikipedia.org/wiki/Domain_of_a_function">domain</a> is to the left and the <a href="https://en.wikipedia.org/wiki/Codomain">codomain</a> is on the right. </p> <p> How do we visualise more complex functions? What if the domain isn't the same as the codomain? </p> <h3 id="eb9ee0e778134e2d8e2c39a09ab76300"> Boolean and <a href="#eb9ee0e778134e2d8e2c39a09ab76300" title="permalink">#</a> </h3> <p> Let's proceed slowly. Let's consider Boolean <em>and</em> next. While this function still involves only Boolean values, it combines two Boolean values into a single Boolean value. It'd seem, then, that in order to visualise this mapping, we'd need two sets to the left, and one to the right. But perhaps a better option is to visualise the domain as pairs of Boolean values: </p> <p> <img src="/content/binary/boolean-and-function-with-domain-and-codomain.png" alt="Boolean and visualised as arrows between sets."> </p> <p> To the left, we have four pairs that each map to the Boolean values on the right. </p> <h3 id="19cc86cf04ae461f936f9f492fe972bd"> Even numbers <a href="#19cc86cf04ae461f936f9f492fe972bd" title="permalink">#</a> </h3> <p> Perhaps using only Boolean values is misleading. Even when dealing with pairs, the above example may fail to illustrate that we can think of any function as a mapping from a domain to a codomain. </p> <p> Imagine that there's such a thing as a 3-bit number. Such a data structure would be able to represent eight different numbers. To be clear, I'm only 'inventing' such a thing as a 3-bit number because it's still manageable to draw a set of eight elements. </p> <p> How would we illustrate a function that returns <em>true</em> if the input is an even 3-bit number, and <em>false</em> otherwise? We could make a diagram like this: </p> <p> <img src="/content/binary/even-function-diagram-with-domain-and-codomain.png" alt="Set diagram of a function to determine whether a 3-bit number is even."> </p> <p> On the left-hand side, I've only labelled two of the numbers, but I'm sure you can imagine that the rest of the elements are ordered from top to bottom: <em>0, 1, 2, 3, 4, 5, 6, 7</em>. To the right, the two elements are <em>true</em> (top) and <em>false</em> (bottom). </p> <p> Given this illustration, I'm sure you can extrapolate to 32-bit integers and so on. It's impractical to draw, but the concept is the same. </p> <h3 id="15f67395fdf24c79945cb1e2b08c1625"> Encoding <a href="#15f67395fdf24c79945cb1e2b08c1625" title="permalink">#</a> </h3> <p> So far, we've only looked at functions where the codomain is the set of Boolean values. How does it look with other codomains? </p> <p> We could, for example, imagine a function that 'encodes' Boolean values as 3-bit numbers, <em>false</em> corresponding (arbitrarily) to <em>5</em> and <em>true</em> to <em>2</em>. The diagram for that function looks like this: </p> <p> <img src="/content/binary/boolean-encoding-as-3-bit-number.png" alt="Set diagram of encoding Boolean values as 3-bit numbers."> </p> <p> Now the set of Boolean values is on the left, with <em>true</em> on top. </p> <h3 id="d51e56d3e298439c95abb398a5183efc"> A function as a pipe <a href="#d51e56d3e298439c95abb398a5183efc" title="permalink">#</a> </h3> <p> In all examples, we have the domain to the left and the codomain on the right, connected with arrows. Sometimes, however, we may want to think about a function as just a single thing, without all the details. After all, the diagrams in this article are simple only because the examples are toy examples. Even a simple function like this one would require a huge diagram: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsPrime</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">candidate</span>)</pre> </p> <p> An input type of <code>int</code> corresponds to a set with 4,294,967,296 elements. That's a big set to draw, and a lot of arrows, too! </p> <p> So perhaps, instead, we'd like to have a way to illustrate a function without all the details, yet still retaining this set-based way of thinking. </p> <p> Let's return to one of the earlier examples, but add a shape around it all: </p> <p> <img src="/content/binary/even-function-diagram-in-a-pipe.png" alt="Set diagram of even function enclosed in pipe."> </p> <p> This seems like a fair addition to make. It starts to look like the function is enclosed in a pipe. Let's make the pipe opaque: </p> <p> <img src="/content/binary/horizontal-pipe.png" alt="Horizontal pipe."> </p> <p> In architecture diagrams, a horizontal pipe is a common way to illustrate that some sort of data processing takes place, so this figure should hardly be surprising. </p> <h3 id="81976b18ccaa40c4af2866681cd2c3bb"> Composition <a href="#81976b18ccaa40c4af2866681cd2c3bb" title="permalink">#</a> </h3> <p> You may say that I've been cheating. After all, in a figure like the one that illustrates an <code>isEven</code> function, the domain is larger than the codomain, yet I've kept both ovals of the same size. Wouldn't the following be a fairer depiction? </p> <p> <img src="/content/binary/even-function-diagram-with-smaller-codomain.png" alt="Set diagram where the codomain is drawn smaller."> </p> <p> If we try to enclose this diagram in an opaque pipe, it'd look like this: </p> <p> <img src="/content/binary/horizontal-cone.png" alt="Horizontal cone."> </p> <p> This mostly looks like a (bad) perspective drawing of a pipe, but it does start to suggest how functions fit together. For example, the output of this <code>isEven</code> function is the Boolean set, which is also the input of, for example the Boolean negation function (<code>!</code> or <code>not</code>). This means that if the shapes fit together, we can compose the pipes: </p> <p> <img src="/content/binary/horizontal-cone-continued-with-pipe.png" alt="Horizontal cone composed with horizontal pipe."> </p> <p> Continuing this line of thinking, we can keep on composing the shapes as long as the output fits the input of the next function. For example, the output of Boolean negation is still the Boolean set, which is also the domain of the above 'encoding' function: </p> <p> <img src="/content/binary/cone-pipe-cone.png" alt="Narrowing cone composed with pipe and widening cone."> </p> <p> We can even, if we'd like to peek into the composition, make the pipes transparent again, to illustrate what's going on: </p> <p> <img src="/content/binary/transparent-cone-pipe-cone.png" alt="Transparent narrowing cone composed with transparent pipe and transparent widening cone."> </p> <p> As long as the right-hand side of one pipe fits the left-hand side of another pipe, it indicates that you can compose these two functions. </p> <h3 id="ec35e44891d24e87bb57e38225ba3f5a"> Haskell translation <a href="#ec35e44891d24e87bb57e38225ba3f5a" title="permalink">#</a> </h3> <p> For completeness' sake, let's try to express these three functions, as well as their composition, in a programming language. Since <a href="https://www.haskell.org">Haskell</a> already comes with a composition operator (<code>.</code>), it fits nicely. It also already comes with two of the three functions we'll need: </p> <p> <pre><span style="color:#2b91af;">even</span>&nbsp;::&nbsp;<span style="color:blue;">Integral</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">Bool</span> <span style="color:#2b91af;">not</span>&nbsp;::&nbsp;<span style="color:#2b91af;">Bool</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">Bool</span></pre> </p> <p> Thanks to Haskell's type-class feature, <code>even</code> works for any <code>Integral</code> instance, so if we imagine that our hypothetical 3-bit number is an <code>Integral</code> instance, it'll work for that type of input as well. </p> <p> The remaining function is trivial to implement: </p> <p> <pre><span style="color:#2b91af;">encode</span>&nbsp;::&nbsp;<span style="color:blue;">Num</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;<span style="color:#2b91af;">Bool</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;a encode&nbsp;&nbsp;True&nbsp;=&nbsp;2 encode&nbsp;False&nbsp;=&nbsp;5</pre> </p> <p> Since <code>Integral</code> is a supertype of <code>Num</code>, if our 3-bit number is an <code>Integral</code> instance, it's also a <code>Num</code> instance. </p> <p> The composition implied by the above figure is this: </p> <p> <pre><span style="color:#2b91af;">composition</span>&nbsp;::&nbsp;<span style="color:blue;">Integral</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;a composition&nbsp;=&nbsp;encode&nbsp;.&nbsp;<span style="color:blue;">not</span>&nbsp;.&nbsp;<span style="color:blue;">even</span></pre> </p> <p> Haskell is typically read from right to left, so this composition starts with <code>even</code>, continues with <code>not</code>, and concludes with <code>encode</code>. </p> <p> Let's call it: </p> <p> <pre>&gt; composition 3 2 &gt; composition 4 5</pre> </p> <p> <code>composition 3</code> first passes through <code>even</code>, which returns <code>False</code>. <code>False</code> then passes through <code>not</code>, which returns <code>True</code>. Finally, <code>True</code> passes through <code>encode</code>, which returns <code>2</code>. </p> <p> I'll leave the exegesis of <code>composition 4</code> as an exercise for the reader. </p> <h3 id="6ece689713714da8adacda590fa3dc7d"> C# translation <a href="#6ece689713714da8adacda590fa3dc7d" title="permalink">#</a> </h3> <p> In C#, imagine that an <code>Int3</code> data type exists. You can now define the three functions like this: </p> <p> <pre>Func&lt;Int3,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">isEven</span>&nbsp;=&nbsp;<span style="color:#1f377f;">number</span>&nbsp;=&gt;&nbsp;number.IsEven; Func&lt;<span style="color:blue;">bool</span>,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">not</span>&nbsp;=&nbsp;<span style="color:#1f377f;">b</span>&nbsp;=&gt;&nbsp;!b; Func&lt;<span style="color:blue;">bool</span>,&nbsp;Int3&gt;&nbsp;<span style="color:#1f377f;">encode</span>&nbsp;=&nbsp;<span style="color:#1f377f;">b</span>&nbsp;=&gt;&nbsp;b&nbsp;?&nbsp;(Int3)2&nbsp;:&nbsp;(Int3)5;</pre> </p> <p> Given a <code>Compose</code> extension method on <code>Func&lt;A, B&gt;</code>, you can now compose the functions like this: </p> <p> <pre>Func&lt;Int3,&nbsp;Int3&gt;&nbsp;<span style="color:#1f377f;">composition</span>&nbsp;=&nbsp;isEven.Compose(not).Compose(encode);</pre> </p> <p> This composition works just like the above Haskell example, and produces the same results. </p> <h3 id="82b6205678464b8489e661774fb2412f"> Conclusion <a href="#82b6205678464b8489e661774fb2412f" title="permalink">#</a> </h3> <p> A function takes input and returns output. Even if the function takes multiple arguments, we <a href="/2018/01/29/argument-list-isomorphisms">can think of an argument as a single object</a>: a tuple or Parameter Object. </p> <p> Thus, we can think of a function as a mapping from one set to another. While we can illustrate a specific mapping (such as <code>even</code>, <code>not</code>, and <code>encode</code>), it's often <a href="/2021/07/28/referential-transparency-fits-in-your-head">useful to think of a function as a single abstract thing</a>. When we think of functions as mappings from sets to sets, it makes intuitive sense to visualise the abstraction as a pipe. </p> <p> This visual metaphor works for object-oriented programming as well. With sufficient mental gymnastics, <a href="/2018/01/22/function-isomorphisms">functions are isomorphic to methods</a>, so the pipe metaphor works beyond <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. </p> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Types as sets https://blog.ploeh.dk/2021/11/15/types-as-sets 2021-11-15T06:37:00+00:00 Mark Seemann <div id="post"> <p> <em>To a certain degree, you can think of static types as descriptions of sets.</em> </p> <p> If you've ever worked with C#, Java, <a href="https://fsharp.org">F#</a>, <a href="https://www.haskell.org">Haskell</a>, or other compiled languages, you've encountered <em>static types</em> in programming. In school, you've probably encountered basic <a href="https://en.wikipedia.org/wiki/Set_theory">set theory</a>. The two relate to each other in illuminating ways. </p> <p> To be clear, I'm neither a mathematician nor a computer scientist, so I'm only basing this article on my layman's understanding of these topics. Still, I find some of the correspondences to be useful when thinking about certain programming topics. </p> <h3 id="3d5852c69bd04cea82693033796f7a59"> Two elements <a href="#3d5852c69bd04cea82693033796f7a59" title="permalink">#</a> </h3> <p> What's the simplest possible set? For various definitions of <em>simple</em>, probably the empty set. After that? The singleton set. We'll skip these, and instead start with a set with two elements: </p> <p> <img src="/content/binary/two-element-set.png" alt="Set with two elements."> </p> <p> If you had to represent such a set in code, how would you do it? </p> <p> First, you'd have to figure out how to distinguish the two elements from each other. Giving each a label seems appropriate. What do you call them? Yin and yang? Church and state? Alice and Bob? </p> <p> And then, how do you represent the labels in code, keeping in mind that they somehow must 'belong to the same set'? Perhaps as an <code>enum</code>? </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">enum</span>&nbsp;<span style="color:#2b91af;">Dualism</span> { &nbsp;&nbsp;&nbsp;&nbsp;Yin, &nbsp;&nbsp;&nbsp;&nbsp;Yang }</pre> </p> <p> As a data definition, though, an <code>enum</code> is a poor choise because the underlying data type is an integer (<code>int</code> by default). Thus, a method like this compiles and executes just fine: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Dualism&nbsp;<span style="color:#74531f;">YinOrYang</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;(Dualism)42; }</pre> </p> <p> The <code>Dualism</code> returned by the function is neither <code>Yin</code> nor <code>Yang</code>. </p> <p> So, how do you represent a set with two elements in code? One option would be to <a href="/2018/05/22/church-encoding">Church encode</a> it (try it! It's a good exercise), but perhaps you find something like the following simpler: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Dualism</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Dualism&nbsp;&nbsp;Yin&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Dualism(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Dualism&nbsp;Yang&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Dualism(&nbsp;<span style="color:blue;">true</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Dualism</span>(<span style="color:blue;">bool</span>&nbsp;<span style="color:#1f377f;">isYang</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsYang&nbsp;=&nbsp;isYang; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;IsYang&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;IsYin&nbsp;=&gt;&nbsp;!IsYang; }</pre> </p> <p> With this design, a method like <code>YinOrYang</code> can't cheat, but must return either <code>Yin</code> or <code>Yang</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Dualism&nbsp;<span style="color:#74531f;">YinOrYang</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Dualism.Yin; }</pre> </p> <p> Notice that this variation is based entirely off a single member: <code>IsYang</code>, which is a Boolean value. </p> <p> In fact, this implementation is isomorphic to <code>bool</code>. You can create a <code>Dualism</code> instance from a <code>bool</code>, and you can convert that instance back to a Boolean value via <code>IsYang</code>, without loss of information. </p> <p> This holds for any two-element set: it's isomorphic to <code>bool</code>. You could say that the data type <code>bool</code> is equivalent to 'the' two-element set. </p> <h3 id="dc3052aa0c574a3684a7a295b765ce80"> More, but still few, elements <a href="#dc3052aa0c574a3684a7a295b765ce80" title="permalink">#</a> </h3> <p> Is there a data type that corresponds to a three-element set? Again, you can always use Church encoding to describe a data type with three cases, but in C#, the easiest backing type would probably be <code>bool?</code> (<code>Nullable&lt;bool&gt;</code>). When viewed as a set, it's a set inhabited by the three values <code>false</code>, <code>true</code>, and <code>null</code>. </p> <p> How about a set with four elements? A pair of Boolean values seems appropriate: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Direction</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Direction&nbsp;North&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Direction(<span style="color:blue;">false</span>,&nbsp;<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Direction&nbsp;South&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Direction(<span style="color:blue;">false</span>,&nbsp;&nbsp;<span style="color:blue;">true</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Direction&nbsp;&nbsp;East&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Direction(&nbsp;<span style="color:blue;">true</span>,&nbsp;<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Direction&nbsp;&nbsp;West&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Direction(&nbsp;<span style="color:blue;">true</span>,&nbsp;&nbsp;<span style="color:blue;">true</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Direction</span>(<span style="color:blue;">bool</span>&nbsp;<span style="color:#1f377f;">isEastOrWest</span>,&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#1f377f;">isLatter</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsEastOrWest&nbsp;=&nbsp;isEastOrWest; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsLatter&nbsp;=&nbsp;isLatter; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;IsEastOrWest&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;IsLatter&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} }</pre> </p> <p> The <code>Direction</code> class is backed by two Boolean values. We can say that a four-element set is isomorphic to a pair of Boolean values. </p> <p> How about a five-element set? If a four-element set corresponds to a pair of Boolean values, then perhaps a pair of one Boolean value and one <code>Nullable&lt;bool&gt;</code>? </p> <p> Alas, that doesn't work. When combining types, the number of possible combinations is the product, not the sum, of individual types. So, a pair of <code>bool</code> and <code>bool?</code> would support 2&nbsp;×&nbsp;3&nbsp;=&nbsp;6 combinations: <code>(false, null)</code>, <code>(false, false)</code>, <code>(false, true)</code>, <code>(true, null)</code>, <code>(true, false)</code>, and <code>(true, true)</code>. </p> <p> Again, a Church encoding (try it!) is an option, but you could also do something like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Spice</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Spice&nbsp;&nbsp;&nbsp;Posh&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Spice(0); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Spice&nbsp;&nbsp;Scary&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Spice(1); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Spice&nbsp;&nbsp;&nbsp;Baby&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Spice(2); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Spice&nbsp;Sporty&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Spice(3); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Spice&nbsp;Ginger&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Spice(4); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">int</span>&nbsp;id; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">Spice</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">id</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.id&nbsp;=&nbsp;id; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;Spice&nbsp;<span style="color:#1f377f;">spice</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;==&nbsp;spice.id; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;HashCode.Combine(id); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This seems like cheating, since it uses a much larger underlying data type (<code>int</code>), but it still captures the essence of a set with five elements. You can't add more elements, or initialise the class with an out-of-range <code>id</code> since the constructor is private. </p> <p> The point isn't so much how to implement particular classes, but rather that if you can enumerate all possible values of a type, you can map a type to a set, and vice versa. </p> <h3 id="fa41b9eb292947728ad3bd7d1ff3ff3c"> More elements <a href="#fa41b9eb292947728ad3bd7d1ff3ff3c" title="permalink">#</a> </h3> <p> Which type corresponds to this set? </p> <p> <img src="/content/binary/256-element-set.png" alt="A 256-element set."> </p> <p> I hope that by now, it's clear that this set could correspond to infinitely many types. It's really only a matter of what we call the elements. </p> <p> If we call the first element <code>0</code>, the next one <code>1</code>, and then <code>2</code>, <code>3</code>, and so on up to <code>255</code>, the set corresponds to an unsigned byte. If we call the elements <code>-128</code>, <code>-127</code>, <code>-126</code> up to <code>127</code>, the set corresponds to a signed byte. They are, however, isomorphic. </p> <p> Likewise, a set with 65,536 elements corresponds to a 16-bit integer, and so on. This also holds for 32-bit integers, 64-bit integers, and even floating point types like <code>float</code> and <code>double</code>. These sets are just too large to draw. </p> <h3 id="f3ebcbb8b5844dcaaa0dbff01b68a571"> Infinite sets <a href="#f3ebcbb8b5844dcaaa0dbff01b68a571" title="permalink">#</a> </h3> <p> While most languages have built-in number types based on a fixed number of bytes, some languages also come with number types that support arbitrarily large numbers. .NET has <a href="https://docs.microsoft.com/dotnet/api/system.numerics.biginteger">BigInteger</a>, <a href="https://www.haskell.org">Haskell</a> comes with <code>Integer</code>, and so on. These numbers aren't truly infinite, but are limited by machine capacity rather than the data structure used to represent them in memory. </p> <p> Another example of a type with arbitrary size is the ubiquitous <code>string</code>. There's no strict upper limit to how large strings you can create, although, again, your machine will ultimately run out of memory or disk space. </p> <p> Theoretically, there are infinitely many strings, so, like <code>BigInteger</code>, <code>string</code> corresponds to an infinite set. This also implies that <code>string</code> and <code>BigInteger</code> are isomorphic, but that shouldn't really be that surprising, since everything that's happening on a computer is already encoded as (binary) numbers - including strings. </p> <p> Any class that contains a <code>string</code> field is therefore also isomorphic to an (or <em>the?</em>) infinite set. Two <code>string</code> fields also correspond to infinity, as does a <code>string</code> field paired with a <code>bool</code> field, and so on. As soon as you have just one 'infinite type', the corresponding set is infinite. </p> <h3 id="233bc54732794692b4cb877ff92c30a8"> Constrained types <a href="#233bc54732794692b4cb877ff92c30a8" title="permalink">#</a> </h3> <p> How about static types (classes) that use one or more built-in types as backing fields, but on top of that impose 'business rules'? </p> <p> This one, for example, uses a <code>byte</code> as a backing field, but prohibits some values: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">DesByte</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">byte</span>&nbsp;b; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">DesByte</span>(<span style="color:blue;">byte</span>&nbsp;<span style="color:#1f377f;">b</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(12&nbsp;&lt;=&nbsp;b&nbsp;&amp;&amp;&nbsp;b&nbsp;&lt;=&nbsp;19) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentOutOfRangeException(nameof(b),&nbsp;<span style="color:#a31515;">&quot;[12,&nbsp;19]&nbsp;not&nbsp;allowed.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.b&nbsp;=&nbsp;b; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> While this class doesn't correspond to the above 256-element set, you can still enumerate all possible values: </p> <p> <img src="/content/binary/248-element-set.png" alt="A 248-element set."> </p> <p> But then what about a class like this one? </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Gadsby</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">string</span>&nbsp;manuscript; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Gadsby</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">manuscript</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(manuscript.Contains(<span style="color:#a31515;">&#39;e&#39;</span>,&nbsp;StringComparison.OrdinalIgnoreCase)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;The&nbsp;manuscript&nbsp;may&nbsp;not&nbsp;contain&nbsp;the&nbsp;letter&nbsp;&#39;e&#39;.&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(manuscript)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.manuscript&nbsp;=&nbsp;manuscript; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> While the constructor prohibits any string that contains the letter <em>e</em>, you can still create infinitely many <code>string</code> values even with that constraint. </p> <p> You can, however, still conceivably enumerate all possible <code>Gadsby</code> values, although the corresponding set would be infinitely large. </p> <p> Obviously, this isn't practical, but the point isn't one of practicality. The point is that you can think of types as sets. </p> <h3 id="0c33ef61fa3e4758b49b7c055ea07c65"> Function types <a href="#0c33ef61fa3e4758b49b7c055ea07c65" title="permalink">#</a> </h3> <p> So far we've only covered 'values', even though it's trivial to create types that correspond to infinitely large sets. </p> <p> In type systems, functions also have types. In Haskell, for example, the <em>type</em> <code>Int -&gt; Bool</code> indicates a function that takes an <code>Int</code> as input and return a <code>Bool</code>. This might for example be a function that checks whether the number is even. </p> <p> Likewise, we can write the type of <code>not</code> (Boolean negation) as <code>Bool -&gt; Bool</code>. In a set diagram, we can illustrate it like this: </p> <p> <img src="/content/binary/not-function-set-diagram.png" alt="Boolean negation set diagram."> </p> <p> Each element points to the other one: <em>true</em> points to <em>false</em>, and vice versa. Together, the two arrows completely describe the <code>not</code> function (the <code>!</code> operator in C#). </p> <p> <img src="/content/binary/not-function-arrow-set.png" alt="The two arrows describing Boolean negation themselves form a set."> </p> <p> If we remove the original elements (<em>true</em> and <em>false</em>) of the set, it becomes clearer that these two arrows also form a set. </p> <p> In general, we can think of functions as sets of arrows, but still sets. Many of these sets are infinite. </p> <h3 id="3dfcc401e1d248888bd2032bfa05f4f4"> Conclusion <a href="#3dfcc401e1d248888bd2032bfa05f4f4" title="permalink">#</a> </h3> <p> Set theory is a branch of mathematics, and so is type theory. Having no formal education in either, I don't claim that types and sets are the same. A quick web search implies that while there are many similarities between types and sets, there are also differences. In this article, I've highlighted some similarities. </p> <p> Thinking about types as sets can be helpful in everyday programming. In test-driven development, for example, <a href="https://en.wikipedia.org/wiki/Equivalence_partitioning">equivalence partitioning</a> provides insights into which test inputs to use. Being able to consider a <em>system under test's</em> inputs as sets (rather than types) makes this easier. </p> <p> As future articles will cover, it also becomes easier to think about <a href="https://en.wikipedia.org/wiki/Robustness_principle">Postel's law</a> and the <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov substitution principle</a>. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="846a603e9bb84bf69c3f0327db148737"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <blockquote> Any class that contains a <code>string</code> field is therefore also isomorphic to an (or <em>the?</em>) infinite set. </blockquote> <p> It is isomorphic to <em>an</em> infinite set. More generally, any class that contains a field of type <code>T</code> is isomorphic to a set with cardinality at least at big as the cardinality of the inhabitants of <code>T</code>. There are infinite sets with different cardinalities, and <code>string</code> is isomorphic to the smallest of these, which is known as countably infinite or <a href="https://en.wikipedia.org/wiki/Aleph_number#Aleph-nought">Aleph-nought</a>. Any class that contains a field of type <code>string -&gt; bool</code> is isomorphic to a set with cardinality at least <a href="https://en.wikipedia.org/wiki/Aleph_number#Aleph-one">Aleph-one</a> since that function type is isomorphic to a set with that cardinality. </p> </div> <div class="comment-date">2021-11-15 14:39 UTC</div> </div> <div class="comment" id="ff1df88a06aa42349fb56e243299499c"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tyson, thank you for writing. I wasn't kidding when I wrote that I'm not a mathematician. Given, however, that <a href="https://www.goodreads.com/review/show/1731926050">I've read and more or less understood</a> <a href="http://amzn.to/2n9MFGh">The Annotated Turing</a>, I should have known better. That book begins with a lucid explanation of Cantor's theorem. </p> <p> Does this practically impact the substance of the present article? </p> </div> <div class="comment-date">2021-11-16 06:51 UTC</div> </div> <div class="comment" id="13a45f6dddad4d73a1b54459c16337a0"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <blockquote> Does this practically impact the substance of the present article? </blockquote> <p> Nope. I think the article is good. I think everything you said is correct. I just wanted to elaborate a bit at the one point where you conveyed some hesitation. </p> </div> <div class="comment-date">2021-11-20 15:52 UTC</div> </div> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Reader as a profunctor https://blog.ploeh.dk/2021/11/08/reader-as-a-profunctor 2021-11-08T07:01:00+00:00 Mark Seemann <div id="post"> <p> <em>Any function gives rise to a profunctor. An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2021/11/01/profunctors">a short article series about profunctors</a>. It assumes that you've read the introduction. </p> <p> Previous articles in <a href="/2018/03/19/functors-applicatives-and-friends">the overall article series on functors and similar abstractions</a> discussed <a href="/2021/08/30/the-reader-functor">Reader as both a covariant functor</a>, as well as <a href="/2021/10/04/reader-as-a-contravariant-functor">a contravariant functor</a>. As the profunctor introduction intimated, if you combine the properties of both co- and contravariance, you'll have a profunctor. </p> <p> There's <a href="/2018/03/22/functors">a wide selection of well-known functors</a> and <a href="/2021/09/02/contravariant-functors">a smaller selection of contravariant functors</a>. Of all those that I've covered so far, only one appears in both lists: Reader. </p> <h3 id="3f3f21d3e3024108801a73605ea1194e"> Reader <a href="#3f3f21d3e3024108801a73605ea1194e" title="permalink">#</a> </h3> <p> Consider, again, this <code>IReader</code> interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReader</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;<span style="color:#74531f;">Run</span>(R&nbsp;<span style="color:#1f377f;">environment</span>); }</pre> </p> <p> When discussing <code>IReader</code> as a covariant functor, we'd fix <code>R</code> and let <code>A</code> vary. When discussing the same interface as a contravariant functor, we'd fix <code>A</code> and let <code>R</code> vary. If you allow both to vary freely, you have a profunctor. </p> <p> As the profunctor overview article asserted, you can implement <code>ContraMap</code> and <code>Select</code> with <code>DiMap</code>, or you can implement <code>DiMap</code> with <code>ContraMap</code> and <code>Select</code>. Since previous articles have supplied both <code>Select</code> and <code>ContraMap</code> for <code>IReader</code>, it's a natural opportunity to see how to implement <code>DiMap</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IReader&lt;R1,&nbsp;A1&gt;&nbsp;<span style="color:#74531f;">DiMap</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">R1</span>,&nbsp;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">A1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IReader&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">reader</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;R1,&nbsp;R&gt;&nbsp;<span style="color:#1f377f;">contraSelector</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;A,&nbsp;A1&gt;&nbsp;<span style="color:#1f377f;">coSelector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;reader.ContraMap(contraSelector).Select(coSelector); }</pre> </p> <p> You simply pass <code>contraSelector</code> to <code>ContraMap</code> and <code>coSelector</code> to <code>Select</code>, while chaining the two method calls. You can also flip the order in which you call these two functions - as long as they are both <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>, it'll make no difference. You'll shortly see an example of flipping the order. </p> <p> First, though, an example of using <code>DiMap</code>. Imagine that you have this <code>IReader</code> implementation: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TotalSecondsReader</span>&nbsp;:&nbsp;IReader&lt;TimeSpan,&nbsp;<span style="color:blue;">double</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">double</span>&nbsp;<span style="color:#74531f;">Run</span>(TimeSpan&nbsp;<span style="color:#1f377f;">environment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;environment.TotalSeconds; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This class converts a <code>TimeSpan</code> value into the total number of seconds represented by that duration. You can project this Reader in both directions using <code>DiMap</code>: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ReaderDiMapExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;TimeSpan,&nbsp;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">reader</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TotalSecondsReader(); &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;DateTime,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.DiMap((DateTime&nbsp;<span style="color:#1f377f;">dt</span>)&nbsp;=&gt;&nbsp;dt.TimeOfDay,&nbsp;<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;d&nbsp;%&nbsp;2&nbsp;==&nbsp;0); &nbsp;&nbsp;&nbsp;&nbsp;Assert.True(projection.Run(<span style="color:blue;">new</span>&nbsp;DateTime(3271,&nbsp;12,&nbsp;11,&nbsp;2,&nbsp;3,&nbsp;4))); }</pre> </p> <p> This example maps the Reader from <code>TimeSpan</code> to <code>DateTime</code> by mapping in the opposite direction: The lambda expression <code>(DateTime dt) =&gt; dt.TimeOfDay</code> returns the time of day of a given <code>DateTime</code>. This value is a <code>TimeSpan</code> value representing the time passed since midnight on that date. </p> <p> The example also checks whether or not a <code>double</code> value is an even number. </p> <p> When the resulting <code>projection</code> is executed, the expected result is <code>true</code> because the input date and time is first converted to a time of day (<em>02:03:04</em>) by the <code>contraSelector</code>. Then <code>TotalSecondsReader</code> converts that duration to the total number of seconds: <em>2 * 60 * 60 + 3 * 60 + 4 = 7,384</em>. Finally, <em>7,384</em> is an even number, so the output is <code>true</code>. </p> <h3 id="536f69bb15094519becd4066266c1088"> Raw functions <a href="#536f69bb15094519becd4066266c1088" title="permalink">#</a> </h3> <p> As already explained in the previous Reader articles, the <code>IReader</code> interface is mostly a teaching device. In a language where you can treat functions as values, you don't need the interface. In C#, for example, the standard function delegates suffice. You can implement <code>DiMap</code> directly on <code>Func&lt;A, B&gt;</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;R1,&nbsp;A1&gt;&nbsp;<span style="color:#74531f;">DiMap</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">R1</span>,&nbsp;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">A1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Func&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">func</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;R1,&nbsp;R&gt;&nbsp;<span style="color:#1f377f;">contraSelector</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;A,&nbsp;A1&gt;&nbsp;<span style="color:#1f377f;">coSelector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;func.Select(coSelector).ContraMap(contraSelector); }</pre> </p> <p> As promised, I've here flipped the order of methods in the chain, so that the implementation first calls <code>Select</code> and then <code>ContraMap</code>. This is entirely arbitrary, and I only did it to demonstrate that the order doesn't matter. </p> <p> Here's another usage example: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">AreaOfDate</span>() { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;Version,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">func</span>&nbsp;=&nbsp;<span style="color:#1f377f;">v</span>&nbsp;=&gt;&nbsp;v.Major&nbsp;+&nbsp;v.Minor&nbsp;*&nbsp;v.Build; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;DateTime,&nbsp;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;func.DiMap( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(DateTime&nbsp;<span style="color:#1f377f;">dt</span>)&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Version(dt.Year,&nbsp;dt.Month,&nbsp;dt.Day), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;i&nbsp;*&nbsp;i&nbsp;*&nbsp;Math.PI); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expected:&nbsp;16662407.390443427686297314140028, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actual:&nbsp;projection(<span style="color:blue;">new</span>&nbsp;DateTime(1991,&nbsp;12,&nbsp;26))); }</pre> </p> <p> This example starts with a nonsensical function that calculates a number from a <code>Version</code> value. Using <code>DiMap</code> the example then transforms <code>func</code> into a function that produces a <code>Version</code> from a <code>DateTime</code> and also calculates the area of a circle with the radius <code>i</code>. </p> <p> Clearly, this isn't a <em>useful</em> piece of code - it only demonstrates how <code>DiMap</code> works. </p> <h3 id="e060b80958e44aa3a88d5bcfad34335b"> Identity law <a href="#e060b80958e44aa3a88d5bcfad34335b" title="permalink">#</a> </h3> <p> As stated in the profunctor introduction, I don't intend to make much of the profunctor laws, since they are only reiterations of the (covariant) functor and contravariant functor laws. Still, an example (not a proof) of the profunctor identity law may be in order: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ProfunctorIdentityLaw</span>() { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;Guid,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">byteRange</span>&nbsp;=&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&gt;&nbsp;g.ToByteArray().Max()&nbsp;-&nbsp;g.ToByteArray().Min(); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;Guid,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">projected</span>&nbsp;=&nbsp;byteRange.DiMap&lt;Guid,&nbsp;Guid,&nbsp;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;(id,&nbsp;id); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">guid</span>&nbsp;=&nbsp;Guid.NewGuid(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(byteRange(guid),&nbsp;projected(guid)); }</pre> </p> <p> This example uses another silly function. Given any <code>Guid</code>, the <code>byteRange</code> function calculates the difference between the largest and smallest byte in the value. Projecting this function with the identity function <code>id</code> along both axes should yield a function with the same behaviour. The <a href="/2013/06/24/a-heuristic-for-formatting-code-according-to-the-aaa-pattern">assertion phase</a> generates an arbitrary <code>Guid</code> and verifies that both <code>byteRange</code> and <code>projected</code> produce the same resulting value. </p> <h3 id="531348d1ee0f40bca3b6a18d1d0665ec"> Haskell <a href="#531348d1ee0f40bca3b6a18d1d0665ec" title="permalink">#</a> </h3> <p> As usual, I've adopted many of the concepts and ideas from <a href="https://www.haskell.org">Haskell</a>. The notion of a profunctor is so exotic that, unlike <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">the Contravariant type class</a>, it's not (to my knowledge) part of the <em>base</em> library. Not that I've ever felt the need to import it, but if I did, I would probably use <a href="https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html">Data.Profunctor</a>. This module defines a <code>Profunctor</code> type class, of which a normal function <code>(-&gt;)</code> is an instance. The type class defines the <code>dimap</code> function. </p> <p> We can replicate the above <code>AreaOfDate</code> example using the <code>Profunctor</code> type class, and the types and functions in <a href="https://hackage.haskell.org/package/time/docs/Data-Time.html">the time library</a>. </p> <p> First, I'll implement <code>func</code> like this: </p> <p> <pre><span style="color:#2b91af;">func</span>&nbsp;::&nbsp;<span style="color:blue;">Num</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;(a,&nbsp;a,&nbsp;a)&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;a func&nbsp;(maj,&nbsp;<span style="color:blue;">min</span>,&nbsp;bld)&nbsp;=&nbsp;maj&nbsp;+&nbsp;<span style="color:blue;">min</span>&nbsp;*&nbsp;bld</pre> </p> <p> Instead of using a <code>Version</code> type (which I'm not sure exists in the 'standard' Haskell libraries) this function just uses a triple (three-tuple). </p> <p> The projection is a bit more involved: </p> <p> <pre><span style="color:#2b91af;">projection</span>&nbsp;::&nbsp;<span style="color:blue;">Day</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">Double</span> projection&nbsp;= &nbsp;&nbsp;dimap &nbsp;&nbsp;&nbsp;&nbsp;((\(maj,&nbsp;<span style="color:blue;">min</span>,&nbsp;bld)&nbsp;-&gt;&nbsp;(<span style="color:blue;">fromInteger</span>&nbsp;maj,&nbsp;<span style="color:blue;">min</span>,&nbsp;bld))&nbsp;.&nbsp;toGregorian) &nbsp;&nbsp;&nbsp;&nbsp;(\i&nbsp;-&gt;&nbsp;<span style="color:blue;">toEnum</span>&nbsp;(i&nbsp;*&nbsp;i)&nbsp;*&nbsp;<span style="color:blue;">pi</span>) &nbsp;&nbsp;&nbsp;&nbsp;func</pre> </p> <p> It basically does the same as the <code>AreaOfDate</code>, but the lambda expressions look more scary because of all the brackets and conversions. Haskell isn't always more succinct than C#. </p> <p> <pre>&gt; projection $ fromGregorian 1991 12 26 1.6662407390443427e7</pre> </p> <p> Notice that GHCi returns the result in scientific notation, so while the decimal separator seems to be oddly placed, the result is the same as in the C# example. </p> <h3 id="91777248e4394855a60f725dbd3c91d3"> Conclusion <a href="#91777248e4394855a60f725dbd3c91d3" title="permalink">#</a> </h3> <p> The Reader functor is not only a (covariant) functor and a contravariant functor. Since it's both, it's also a profunctor. And so what? </p> <p> This knowledge doesn't seem immediately applicable, but shines an interesting light on the fabric of code. If you squint hard enough, <a href="/2018/01/08/software-design-isomorphisms">most programming constructs look like functions</a>, and functions are profunctors. I don't intent to go so far as to claim that 'everything is a profunctor', but the Reader profunctor is ubiquitous. </p> <p> I'll return to this insight in a future article. </p> <p> <strong>Next:</strong> <a href="/2022/03/28/monads">Monads</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Profunctors https://blog.ploeh.dk/2021/11/01/profunctors 2021-11-01T06:59:00+00:00 Mark Seemann <div id="post"> <p> <em>Functors that are both co- and contravariant. An article for C# programmers.</em> </p> <p> This article series is part of <a href="/2018/03/19/functors-applicatives-and-friends">a larger series of articles about functors, applicatives, and other mappable containers</a>. Particularly, you've seen examples of both <a href="/2018/03/22/functors">functors</a> and <a href="/2021/09/02/contravariant-functors">contravariant functors</a>. </p> <p> What happens if you, so to speak, combine those two? </p> <h3 id="20df8ada70644ca2a4a5363f05f89216"> Mapping in both directions <a href="#20df8ada70644ca2a4a5363f05f89216" title="permalink">#</a> </h3> <p> A <em>profunctor</em> is like a <a href="/2018/12/24/bifunctors">bifunctor</a>, except that it's contravariant in one of its arguments (and covariant in the other). Usually, you'd list the contravariant argument first, and the covariant argument second. By that convention, a hypothetical <code>Profunctor&lt;A, B&gt;</code> would be contravariant in <code>A</code> and covariant in <code>B</code>. </p> <p> In order to support such mapping, you could give the class a <code>DiMap</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Profunctor</span>&lt;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">B</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Profunctor&lt;A1,&nbsp;B1&gt;&nbsp;<span style="color:#74531f;">DiMap</span>&lt;<span style="color:#2b91af;">A1</span>,&nbsp;<span style="color:#2b91af;">B1</span>&gt;(Func&lt;A1,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">contraSelector</span>,&nbsp;Func&lt;B,&nbsp;B1&gt;&nbsp;<span style="color:#1f377f;">coSelector</span>) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;...</span></pre> </p> <p> Contrary to (covariant) functors, where C# will light up some extra compiler features if you name the mapping method <code>Select</code>, there's no extra language support for profunctors. Thus, you can call the method whatever you like, but here I've chosen the name <code>DiMap</code> just because that's what the <a href="https://www.haskell.org">Haskell</a> <a href="https://hackage.haskell.org/package/profunctors">Profunctors package</a> calls the corresponding function. </p> <p> Notice that in order to map the contravariant type argument <code>A</code> to <code>A1</code>, you must supply a selector that moves in the contrary direction: from <code>A1</code> to <code>A</code>. Mapping the covariant type argument <code>B</code> to <code>B1</code>, on the other hand, goes in the same direction: from <code>B</code> to <code>B1</code>. </p> <p> An example might look like this: </p> <p> <pre>Profunctor&lt;TimeSpan,&nbsp;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">profunctor</span>&nbsp;=&nbsp;CreateAProfunctor(); Profunctor&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;profunctor.DiMap&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">bool</span>&gt;(TimeSpan.Parse,&nbsp;<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;d&nbsp;%&nbsp;1&nbsp;==&nbsp;0);</pre> </p> <p> This example starts with a profunctor where the contravariant type is <code>TimeSpan</code> and the covariant type is <code>double</code>. Using <code>DiMap</code> you can map it to a <code>Profunctor&lt;string, bool&gt;</code>. In order to map the <code>profunctor</code> value's <code>TimeSpan</code> to the <code>projection</code> value's <code>string</code>, the method call supplies <code>TimeSpan.Parse</code>: a (partial) function that maps <code>string</code> to <code>TimeSpan</code>. </p> <p> The second argument maps the <code>profunctor</code> value's <code>double</code> to the <code>projection</code> value's <code>bool</code> by checking if <code>d</code> is an integer. The lambda expression <code><span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;d&nbsp;%&nbsp;1&nbsp;==&nbsp;0</code> implements a function from <code>double</code> to <code>bool</code>. That is, the profunctor <em>covaries</em> with that function. </p> <h3 id="3252cf7678234d0697ea0223b5659f5e"> Covariant mapping <a href="#3252cf7678234d0697ea0223b5659f5e" title="permalink">#</a> </h3> <p> Given <code>DiMap</code> you can implement the standard <code>Select</code> method for functors. </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Profunctor&lt;A,&nbsp;B1&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">B1</span>&gt;(Func&lt;B,&nbsp;B1&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;DiMap&lt;A,&nbsp;B1&gt;(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x,&nbsp;selector); }</pre> </p> <p> <a href="/2019/01/07/either-bifunctor">Equivalently to bifunctors</a>, when you have a function that maps both dimensions, you can map one dimension by using the identity function for the dimension you don't need to map. Here I've used the lambda expression <code>x =&gt; x</code> as the identity function. </p> <p> You can use this <code>Select</code> method with standard method-call syntax: </p> <p> <pre>Profunctor&lt;DateTime,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">profunctor</span>&nbsp;=&nbsp;CreateAProfunctor(); Profunctor&lt;DateTime,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;profunctor.Select(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length);</pre> </p> <p> or with query syntax: </p> <p> <pre>Profunctor&lt;DateTime,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">profunctor</span>&nbsp;=&nbsp;CreateAProfunctor(); Profunctor&lt;DateTime,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;<span style="color:blue;">from</span>&nbsp;ts&nbsp;<span style="color:blue;">in</span>&nbsp;profunctor &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;ts.Minutes;</pre> </p> <p> All profunctors are also covariant functors. </p> <h3 id="171bd982cd5c48a69690ea10d9dbb7d4"> Contravariant mapping <a href="#171bd982cd5c48a69690ea10d9dbb7d4" title="permalink">#</a> </h3> <p> Likewise, given <code>DiMap</code> you can implement a <code>ContraMap</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Profunctor&lt;A1,&nbsp;B&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">A1</span>&gt;(Func&lt;A1,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;DiMap&lt;A1,&nbsp;B&gt;(selector,&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x); }</pre> </p> <p> Using <code>ContraMap</code> is only possible with normal method-call syntax, since C# has no special understanding of contravariant functors: </p> <p> <pre>Profunctor&lt;<span style="color:blue;">long</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#1f377f;">profunctor</span>&nbsp;=&nbsp;CreateAProfunctor(); Profunctor&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;profunctor.ContraMap&lt;<span style="color:blue;">string</span>&gt;(<span style="color:blue;">long</span>.Parse);</pre> </p> <p> All profunctors are also contravariant functors. </p> <p> While you can implement <code>Select</code> and <code>ContraMap</code> from <code>DiMap</code>, it's also possible to go the other way. If you have <code>Select</code> and <code>ContraMap</code> you can implement <code>DiMap</code>. </p> <h3 id="db28768129484d5d8fcf6591f164c2ad"> Laws <a href="#db28768129484d5d8fcf6591f164c2ad" title="permalink">#</a> </h3> <p> In the overall article series, I've focused on the laws that govern various universal abstractions. In this article, I'm going to treat this topic lightly, since it'd mostly be a reiteration of the laws that govern co- and contravariant functors. </p> <p> The only law I'll highlight is the profunctor identity law, which intuitively is a generalisation of the identity laws for co- and contravariant functors. If you map a profunctor in both dimensions, but use the identity function in both directions, nothing should change: </p> <p> <pre>Profunctor&lt;Guid,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">profunctor</span>&nbsp;=&nbsp;CreateAProfunctor(); Profunctor&lt;Guid,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;profunctor.DiMap((Guid&nbsp;<span style="color:#1f377f;">g</span>)&nbsp;=&gt;&nbsp;g,&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s);</pre> </p> <p> Here I've used two lambda expressions to implement the identity function. While they're two different lambda expressions, they both 'implement' the general identity function. If you aren't convinced, we can demonstrate the idea like this instead: </p> <p> <pre>T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; Profunctor&lt;Guid,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">profunctor</span>&nbsp;=&nbsp;CreateAProfunctor(); Profunctor&lt;Guid,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;profunctor.DiMap&lt;Guid,&nbsp;<span style="color:blue;">string</span>&gt;(id,&nbsp;id);</pre> </p> <p> This alternative representation defines a <a href="https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/local-functions">local function</a> called <code>id</code>. Since it's generic, you can use it as both arguments to <code>DiMap</code>. </p> <p> The point of the identity law is that in both cases, <code>projection</code> should be equal to <code>profunctor</code>. </p> <h3 id="7b00d6198531450b86fa49d9f3133806"> Usefulness <a href="#7b00d6198531450b86fa49d9f3133806" title="permalink">#</a> </h3> <p> Are profunctors useful in everyday programming? So far, I've found no particular use for them. This mirrors my experience with contravariant functors, which I also find little use for. Why should we care, then? </p> <p> It turns out that, while we rarely work explicitly with profunctors, they're everywhere. Normal functions are profunctors. </p> <ul> <li><a href="/2021/11/08/reader-as-a-profunctor">Reader as a profunctor</a></li> </ul> <p> In addition to normal functions (which <a href="/2021/08/30/the-reader-functor">are both covariant</a> and <a href="/2021/10/04/reader-as-a-contravariant-functor">contravariant</a>) other profunctors exist. At the time that I'm writing this article, I've no particular plans to add articles about any other profunctors, but if I do, I'll add them to the above list. Examples include Kleisli arrows and profunctor optics. </p> <p> The reason I find it worthwhile to learn about profunctors is that this way of looking at well-behaved functions shines an interesting light on the fabric of computation, so to speak. In <a href="/2021/11/29/postels-law-as-a-profunctor">a future article</a>, I'll expand on that topic. </p> <h3 id="da045552d1064ff88ac2eb7fb4ce18d7"> Conclusion <a href="#da045552d1064ff88ac2eb7fb4ce18d7" title="permalink">#</a> </h3> <p> A <em>profunctor</em> is a functor that is covariant in one dimension and contravariant in another dimension. While various exotic examples exist, the only example that you'd tend to encounter in mainstream programming is the Reader profunctor, also known simply as <em>functions</em>. </p> <p> <strong>Next:</strong> <a href="/2021/11/08/reader-as-a-profunctor">Reader as a profunctor</a>. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="bb0bb9d1bf094c1897f9dd42fb49712c"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <blockquote> Are profunctors useful in everyday programming? So far, I've found no particular use for them. </blockquote> <p> I have not found the concept of a profunctor useful in everyday programming, but I have found one very big use for them. </p> <p> I am the maintainer of <a href="https://github.com/elmish/Elmish.WPF">Elmish.WPF</a>. This project makes it easy to create a WPF application in the style of the Model-View-Update / MVU / <a href="https://guide.elm-lang.org/architecture/">Elm Architecture</a>. In a traditional WPF application, data goes between a view model and WPF via properties on that view model. Elmish.WPF makes that relationship a first-class concept via the type <code>Binding&lt;'model, 'msg&gt;</code>. This type is a profunctor; contravariant in <code>'model</code> and covariant in <code>'msg</code>. The individual mapping functions are <a href="https://github.com/elmish/Elmish.WPF/blob/1a4f4384c469ae22f281ce489a811d772ceba5f7/src/Elmish.WPF/Binding.fs#L724-L725"><code>Binding.mapModel</code></a> and <a href="https://github.com/elmish/Elmish.WPF/blob/1a4f4384c469ae22f281ce489a811d772ceba5f7/src/Elmish.WPF/Binding.fs#L730-L731"><code>Binding.mapMsg</code></a> respectively. </p> <p> This type was not always a profunctor. Recall that a profunctor is not really just a type but a type along with its mapping functions (or a single combined function). In versions 1, 2, and 3 of Elmish.WPF, this type is not a profunctor due to the missing mapping function(s). I added the mapping functions in version 4 (currently a prelease) that makes <code>Binding&lt;'model, 'msg&gt;</code> (along with those functions) a profunctor. This abstraction has made it possible to significantly improve both the internal implementation as well as the public API. </p> <p> As you stated, a single function <code>a -&gt; b</code> is a profunctor; contravariant in <code>a</code> and covariant in <code>b</code>. I think of this as the canonical profunctor, or maybe "the original" profunctor. I think it is interesting to compare each profunctor to this one. In the case of <code>Binding&lt;'model, 'msg&gt;</code>, is implemented by two functions: one from the (view) model to WPF with type <code>'model -> obj</code> that we could call <code>toWpf</code> and one from WPF with type <code>obj -> 'msg</code> that we could call <code>fromWpf</code>. Of course, composing these two functions results in a single function that is a profunctor in exactly the way we expect. </p> <p> Now here is something that I don't understand. In addition to <code>Binding.mapModel</code> and <code>Binding.mapMsg</code>, I have discovered another function with useful behavior in the function <a href="https://github.com/elmish/Elmish.WPF/blob/1a4f4384c469ae22f281ce489a811d772ceba5f7/src/Elmish.WPF/Binding.fs#L727-L728"><code>Binding.mapMsgWithModel</code></a>. Recall that a function <code>a -&gt; b</code> is not just profunctor in (contravariant) <code>a</code> and (covariant) <code>b</code>, but it is also a monad in <code>b</code> (with <code>a</code> fixed). The composed function <code>toWpf &gt;&gt; fromWpf</code> is such a monad and <code>Binding.mapMsgWithModel</code> is its "<code>bind</code>" function. The leads one to think that <code>Binding&lt;'model, 'msg&gt;</code> could be a monad in <code>'msg</code> (with <code>'model</code> fixed). My intuition is that this is not the case, but maybe I am wrong. </p> </div> <div class="comment-date">2021-11-02 01:38 UTC</div> </div> <div class="comment" id="5a203c4b4570460d86a960552dbaada8"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tyson, it's great to learn that there are other examples of useful profunctors in the wild. It might be useful to add it to a 'catalogue' of profunctor examples, if someone ever compiles such a list - but perhaps it's a little to specific for a general-purpose catalogue... </p> <p> After much digging around in the source code you linked, I managed to locate the <a href="https://github.com/elmish/Elmish.WPF/blob/1a4f4384c469ae22f281ce489a811d772ceba5f7/src/Elmish.WPF/Binding.fs#L139-L142">definition of Binding&lt;'model, 'msg&gt;</a>, which, however, turns out to be too complex for me to do a full analysis on a Saturday morning. </p> <p> One of the cases, however, the <a href="https://github.com/elmish/Elmish.WPF/blob/1a4f4384c469ae22f281ce489a811d772ceba5f7/src/Elmish.WPF/Binding.fs#L36-L38">TwoWayData&lt;'model, 'msg&gt;</a> type looks much like a lens - another profunctor example. </p> <p> Might <code>Binding&lt;'model, 'msg&gt;</code> also form a monad? </p> <p> One simple test I've found useful for answering such a question is to consider whether a lawful <code>join</code> function exists. In Haskell, the <code>join</code> function has the type <code>Monad m =&gt; m (m a) -&gt; m a</code>. The intuitive interpretation is that if you can 'flatten' a nested functor, then that functor is also a monad. </p> <p> So the question is: Can you reasonably write a function with the type <code>Binding&lt;'model, Binding&lt;'model, 'msg&gt;&gt; -&gt; Binding&lt;'model, 'msg&gt;</code>? </p> <p> If you can write a lawful implementation of this <code>join</code> function, the <code>Binding&lt;'model, 'msg&gt;</code> forms a monad. </p> </div> <div class="comment-date">2021-11-06 10:56 UTC</div> </div> <div class="comment" id="26dfc57cd0f14444898a53b0a0d6f977"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <p> Thank you for linking to the deinition of <code>Binding&lt;'model, 'msg&gt;</code>. I should have done that. Yes, the <code>TwoWayData&lt;'model, 'msg&gt;</a></code> case is probably the simplest. Good job finding it. I have thought about implementing such a <code>join</code> function, but it doesn't seem possible to me. </p> </div> <div class="comment-date">2021-11-15 14:13 UTC</div> </div> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Functor variance compared to C#'s notion of variance https://blog.ploeh.dk/2021/10/25/functor-variance-compared-to-cs-notion-of-variance 2021-10-25T05:53:00+00:00 Mark Seemann <div id="post"> <p> <em>A note on C# co- and contravariance, and how it relates to functors.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction, and a few of the examples. </p> <p> If you know your way around C# you may know that the language has its own notion of co- and contravariance. Perhaps you're wondering how it fits with contravariant functors. </p> <p> Quite well, fortunately. </p> <h3 id="1469d9fdd00f4a68b4c30a1bf81b7295"> Assignment compatibility <a href="#1469d9fdd00f4a68b4c30a1bf81b7295" title="permalink">#</a> </h3> <p> For the C# perspective on co- and contravariance, <a href="https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/covariance-contravariance">the official documentation</a> is already quite good. It starts with this example of <em>assignment compatibility</em>: </p> <blockquote> <p> <pre><span style="color:green;">//&nbsp;Assignment&nbsp;compatibility.</span> <span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">str</span>&nbsp;=&nbsp;<span style="color:#a31515;">&quot;test&quot;</span>; <span style="color:green;">//&nbsp;An&nbsp;object&nbsp;of&nbsp;a&nbsp;more&nbsp;derived&nbsp;type&nbsp;is&nbsp;assigned&nbsp;to&nbsp;an&nbsp;object&nbsp;of&nbsp;a&nbsp;less&nbsp;derived&nbsp;type.</span> <span style="color:blue;">object</span>&nbsp;<span style="color:#1f377f;">obj</span>&nbsp;=&nbsp;str;</pre> </p> </blockquote> <p> This kind of assignment is always possible, because a <code>string</code> <em>is also already</em> an <code>object</code>. An upcast within the inheritance hierarchy is <em>always</em> possible, so C# automatically allows it. </p> <p> <a href="https://fsharp.org">F#</a>, on the other hand, doesn't. If you try to do something similar in F#, it doesn't compile: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;str&nbsp;=&nbsp;<span style="color:#a31515;">&quot;test&quot;</span> <span style="color:blue;">let</span>&nbsp;obj&nbsp;:&nbsp;obj&nbsp;=&nbsp;str&nbsp;<span style="color:green;">//&nbsp;Doesn&#39;t&nbsp;compile</span></pre> </p> <p> The compiler error is: </p> <blockquote> This expression was expected to have type 'obj' but here has type 'string' </blockquote> <p> You have to explicitly use the upcast operator: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;str&nbsp;=&nbsp;<span style="color:#a31515;">&quot;test&quot;</span> <span style="color:blue;">let</span>&nbsp;obj&nbsp;=&nbsp;str&nbsp;:&gt;&nbsp;obj</pre> </p> <p> When you do that, the explicit type declaration of the value is redundant, so I removed it. </p> <p> In this example, you can think of <code>:&gt;</code> as a function from <code>string</code> to <code>obj</code>: <code>string -&gt; obj</code>. In C#, the equivalent function would be <code>Func&lt;string, object&gt;</code>. </p> <p> These functions always exist for types that are properly related to each other, upcast-wise. You can think of it as a generic function <code>'a -&gt; 'b</code> (or <code>Func&lt;A, B&gt;</code>), with the proviso that <code>A</code> must be 'upcastable' to <code>B</code>: </p> <p> <img src="/content/binary/a-as-a-subtype-of-b.png" alt="Two boxes labeled 'A' and 'B with an arrow pointing from A to B."> </p> <p> In my head, I'd usually think about this as <em>A being a subtype of B</em>, but unless I explain what I mean by <em>subtyping</em>, it usually confuses people. I consider anything that can 'act as' something else a subtype. So <code>string</code> is a subtype of <code>object</code>, but I also consider <code>TimeSpan</code> a subtype of <code>IComparable</code>, because that cast is also always possible: </p> <p> <pre>TimeSpan&nbsp;<span style="color:#1f377f;">twoMinutes</span>&nbsp;=&nbsp;TimeSpan.FromMinutes(2); IComparable&nbsp;<span style="color:#1f377f;">comp</span>&nbsp;=&nbsp;twoMinutes;</pre> </p> <p> Once again, F# is only happy if you explicitly use the <code>:&gt;</code> operator: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;twoMinutes&nbsp;=&nbsp;TimeSpan.FromMinutes&nbsp;2. <span style="color:blue;">let</span>&nbsp;comp&nbsp;=&nbsp;twoMinutes&nbsp;:&gt;&nbsp;IComparable</pre> </p> <p> All this is surely old hat to any .NET developer with a few months of programming under his or her belt. All the same, I want to drive home one last point (that you already know): Automatic upcast conversions are <a href="https://en.wikipedia.org/wiki/Transitive_relation">transitive</a>. Consider a class like <a href="https://docs.microsoft.com/dotnet/api/system.httpstyleuriparser">HttpStyleUriParser</a>, which is part of a small inheritance hierarchy: <code>object -&gt; UriParser -&gt; HttpStyleUriParser</code> (sic, that's how the documentation denotes the inheritance hierarchy; be careful about the arrow direction!). You can upcast an <code>HttpStyleUriParser</code> to both <code>UriParser </code> and <code>object</code>: </p> <p> <pre>HttpStyleUriParser&nbsp;<span style="color:#1f377f;">httParser</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;HttpStyleUriParser(); UriParser&nbsp;<span style="color:#1f377f;">parser</span>&nbsp;=&nbsp;httParser; <span style="color:blue;">object</span>&nbsp;<span style="color:#1f377f;">op</span>&nbsp;=&nbsp;httParser;</pre> </p> <p> Again, the same is true in F#, but you have to explicitly use the <code>:&gt;</code> operator. </p> <p> To recapitulate: C# has a built-in <em>automatic</em> conversion that upcasts. It's also built into F#, but here as an operator that you explicitly have to use. It's like an automatic function from subtype to supertype. </p> <h3 id="7d69802639da4e13aef41faf2a740c19"> Covariance <a href="#7d69802639da4e13aef41faf2a740c19" title="permalink">#</a> </h3> <p> The C# documentation continues with an example of covariance: </p> <blockquote> <p> <pre><span style="color:green;">//&nbsp;Covariance.</span> IEnumerable&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">strings</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;List&lt;<span style="color:blue;">string</span>&gt;(); <span style="color:green;">//&nbsp;An&nbsp;object&nbsp;that&nbsp;is&nbsp;instantiated&nbsp;with&nbsp;a&nbsp;more&nbsp;derived&nbsp;type&nbsp;argument</span> <span style="color:green;">//&nbsp;is&nbsp;assigned&nbsp;to&nbsp;an&nbsp;object&nbsp;instantiated&nbsp;with&nbsp;a&nbsp;less&nbsp;derived&nbsp;type&nbsp;argument.</span> <span style="color:green;">//&nbsp;Assignment&nbsp;compatibility&nbsp;is&nbsp;preserved.</span> IEnumerable&lt;<span style="color:blue;">object</span>&gt;&nbsp;<span style="color:#1f377f;">objects</span>&nbsp;=&nbsp;strings;</pre> </p> </blockquote> <p> Since <code>IEnumerable&lt;T&gt;</code> forms a <a href="/2018/03/22/functors">(covariant) functor</a> you can lift a function <code>Func&lt;A, B&gt;</code> to a function from <code>IEnumerable&lt;A&gt;</code> to <code>IEnumerable&lt;B&gt;</code>. Consider the above example that goes from <code>IEnumerable&lt;string&gt;</code> to <code>IEnumerable&lt;object&gt;</code>. Let's modify the diagram from the functor article: </p> <p> <img src="/content/binary/functor-diagram-for-ienumerable.png" alt="Functor diagram."> </p> <p> Since the C# compiler already knows that an automatic function (<code>:&gt;</code>) exists that converts <code>string</code> to <code>object</code>, it can <em>automatically</em> convert <code>IEnumerable&lt;string&gt;</code> to <code>IEnumerable&lt;object&gt;</code>. You don't have to call <code>Select</code> to do this. The compiler does it for you. </p> <p> How does it do that? </p> <p> It looks for a little annotation on the generic type argument. For covariant types, <a href="https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/covariance-contravariance/creating-variant-generic-interfaces">the relevant keyword</a> is <code>out</code>. And, as expected, the <code>T</code> in <a href="https://docs.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1">IEnumerable&lt;T&gt;</a> is annotated with <code>out</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:blue;">out</span>&nbsp;<span style="color:#2b91af;">T</span>&gt;</pre> </p> <p> The same is true for <a href="https://docs.microsoft.com/dotnet/api/system.func-2">Func&lt;T, TResult&gt;</a>, which <a href="/2021/08/30/the-reader-functor">is both covariant</a> and <a href="/2021/10/04/reader-as-a-contravariant-functor">contravariant</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">delegate</span>&nbsp;TResult&nbsp;<span style="color:#2b91af;">Func</span>&lt;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:blue;">out</span>&nbsp;<span style="color:#2b91af;">TResult</span>&gt;(T&nbsp;<span style="color:#1f377f;">arg</span>);</pre> </p> <p> The <code>in</code> keyword denotes contravariance, but we'll get to that shortly. </p> <p> The reason that covariance is annotated with the <code>out</code> keyword is that covariant type arguments usually sit in the return-type position. The rule is actually a little more nuanced than that, but I'll again refer you to <a href="https://reasonablypolymorphic.com">Sandy Maguire</a>'s <a href="https://www.goodreads.com/review/show/3406773267">excellent</a> book <a href="https://thinkingwithtypes.com">Thinking with Types</a> if you're interested in the details. </p> <h3 id="e409b7a8a3964385bcdffb1fb72e4251"> Contravariance <a href="#e409b7a8a3964385bcdffb1fb72e4251" title="permalink">#</a> </h3> <p> So far, so good. What about contravariance? The C# documentation continues its example: </p> <blockquote> <p> <pre><span style="color:green;">//&nbsp;Contravariance.</span> <span style="color:green;">//&nbsp;Assume&nbsp;that&nbsp;the&nbsp;following&nbsp;method&nbsp;is&nbsp;in&nbsp;the&nbsp;class:</span> <span style="color:green;">//&nbsp;static&nbsp;void&nbsp;SetObject(object&nbsp;o)&nbsp;{&nbsp;}</span> Action&lt;<span style="color:blue;">object</span>&gt;&nbsp;<span style="color:#1f377f;">actObject</span>&nbsp;=&nbsp;SetObject; <span style="color:green;">//&nbsp;An&nbsp;object&nbsp;that&nbsp;is&nbsp;instantiated&nbsp;with&nbsp;a&nbsp;less&nbsp;derived&nbsp;type&nbsp;argument</span> <span style="color:green;">//&nbsp;is&nbsp;assigned&nbsp;to&nbsp;an&nbsp;object&nbsp;instantiated&nbsp;with&nbsp;a&nbsp;more&nbsp;derived&nbsp;type&nbsp;argument.</span> <span style="color:green;">//&nbsp;Assignment&nbsp;compatibility&nbsp;is&nbsp;reversed.</span> Action&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">actString</span>&nbsp;=&nbsp;actObject;</pre> </p> </blockquote> <p> The <a href="https://docs.microsoft.com/dotnet/api/system.action-1">Action&lt;T&gt;</a> delegate <a href="/2021/09/06/the-command-handler-contravariant-functor">gives rise to a contravariant functor</a>. The <code>T</code> is also annotated with the <code>in</code> keyword, since the type argument sits in the input position: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">delegate</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#2b91af;">Action</span>&lt;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">obj</span>)</pre> </p> <p> Again, let's modify the diagram from <a href="/2021/09/02/contravariant-functors">the article about contravariant functors</a>: </p> <p> <img src="/content/binary/contravariant-functor-diagram-for-action.png" alt="Contravariant functor diagram."> </p> <p> Again, since the C# compiler already knows that an automatic function exists that converts <code>string</code> to <code>object</code>, it can <em>automatically</em> convert <code>Action&lt;object&gt;</code> to <code>Action&lt;string&gt;</code>. You don't have to call <code>Contramap</code> to do this. The compiler does it for you. </p> <p> It knows that <code>Action&lt;T&gt;</code> is contravariant because it's annotated with the <code>in</code> keyword. Thus, it allows contravariant assignment. </p> <p> It all checks out. </p> <h3 id="660eb0eaa995410d891e07ec4b978ba6"> Conclusion <a href="#660eb0eaa995410d891e07ec4b978ba6" title="permalink">#</a> </h3> <p> The C# compiler understands co- and contravariance, but while it automatically supports it, it only deals with automatic conversion from subtype to supertype. Thus, for those kinds of conversions, you don't need a <code>Select</code> or <code>ContraMap</code> method. </p> <p> The functor notion of co- and contravariance is a generalisation of how the C# compiler works. Instead of relying on automatic conversions, the <code>Select</code> and <code>ContraMap</code> methods enable you to supply arbitrary conversion functions. </p> <p> <strong>Next:</strong> <a href="/2022/03/21/contravariant-dependency-injection">Contravariant Dependency Injection</a>. </p> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Readability verification https://blog.ploeh.dk/2021/10/18/readability-verification 2021-10-18T07:37:00+00:00 Mark Seemann <div id="post"> <p> <em>How do you know whether the code you wrote is readable?</em> </p> <p> In a recent Twitter thread about pair and mob programming, <a href="https://dannorth.net">Dan North</a> observes: </p> <blockquote> <p> "That’s the tricky problem I was referring to. If you think you can write code that other humans can understand, without collaborating or calibrating with other humans, assuming that an after-the-fact check will always be affirmative, then you are a better programmer than me." </p> <footer><cite><a href="https://twitter.com/tastapod/status/1448184718122487811">Dan North</a></cite></footer> </blockquote> <p> I neither think that I'm a better programmer than Dan nor that, without collaboration, I can write code that other humans can understand. That's why I'd like someone else to <em>review</em> my code. Not write it together with me, but <em>read it</em> after I've written it. </p> <h3 id="b9a6a0093d0c4c2193c4e39d519ef582"> Advantages of pair and ensemble programming <a href="#b9a6a0093d0c4c2193c4e39d519ef582" title="permalink">#</a> </h3> <p> Pair programming and ensemble (AKA <em>mob</em>) programming is an efficient way to develop software. It works for lots of people. I'm not insisting otherwise. </p> <p> By working together, you can pool skills. Imagine working on a feature for a typical web application. This involves user interface, business logic, data access, and possibly other things as well. Few people are experts in all those areas. Personally, I'm comfortable around business logic and data access, but know little about web front-end development. It's great to have someone else's expertise to draw on. </p> <p> By working together in real time, you avoid hand-offs. If I had to help implementing a feature in an asynchronous manner, I'd typically implement domain logic and data access in a REST API, then tell a front-end expert that the API is ready. This way of working <a href="/2020/03/16/conways-law-latency-versus-throughput">introduces wait times into the process</a>, and may also cause rework if it turns out that the way I designed the API doesn't meet the requirements of the front end. </p> <p> Real-time collaboration addresses some of these concerns. It also improves code ownership. In <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, I quote <a href="https://twitter.com/birgitta410">Birgitta Böckeler</a> and <a href="https://sssggr.net">Nina Siessegger</a>: </p> <blockquote> <p> "Consistent pairing makes sure that every line of code was touched or seen by at least 2 people. This increases the chances that anyone on the team feels comfortable changing the code almost anywhere. It also makes the codebase more consistent than it would be with single coders only. </p> <p> "Pair programming alone does not guarantee you achieve collective code ownership. You need to make sure that you also rotate people through different pairs and areas of the code, to prevent knowledge silos." </p> <footer><cite>Birgitta Böckeler and Nina Siessegger, <a href="https://martinfowler.com/articles/on-pair-programming.html">On Pair Programming</a></cite></footer> </blockquote> <p> With mob programming, you take many of these advantages to the next level. If you include a domain expert in the group, you can learn about what the organisation actually needs as you're developing a feature. If you include specialised testers, they may see edge cases or error modes you didn't think of. If you include UX experts, you'll have a chance to develop software that users can actually figure out how to use. </p> <p> There are lots of benefits to be had from pair and ensemble programming. In <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> I recommend that you try it. I've recommended it to my customers. I've had good experiences with it myself: </p> <blockquote> <p> "I’ve used [mob programming] with great success as a programming coach. In one engagement, I spent two to three days a week with a few other programmers, helping them apply test-driven development practices to their production code bases. After a few months of that, I went on vacation. Meanwhile those programmers kept going with test-driven development. Mob programming is great for knowledge transfer." </p> <footer><cite><a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a></cite></footer> </blockquote> <p> <a href="/2021/10/11/serendipity-driven-development">I don't, however, think that it's a one-size-fits-all solution</a>. </p> <h3 id="c57bfb2342d2437596ff90a13fb29c44"> The curse of knowledge <a href="#c57bfb2342d2437596ff90a13fb29c44" title="permalink">#</a> </h3> <p> While outlining the advantages of pair and ensemble programming, I didn't mention readability. I don't see how those ways of working address the problem of writing readable code. </p> <p> I've reviewed code written by pairs, and it was neither more nor less readable than code written by a single programmer. I think that there's an easy-to-understand reason for this. It relates to the <em>curse of knowledge:</em> </p> <blockquote> <p> "In 1990, Elizabeth Newton earned a Ph.D. in psychology at Stanford by studying a simple game in which she assigned people to one of two roles: “tappers” or “listeners.” Tappers received a list of twenty-five well-known songs, such as “Happy Birthday to You” and “The Star-Spangled Banner.” Each tapper was asked to pick a song and tap out the rhythm to a listener (by knocking on a table). The listener’s job was to guess the song, based on the rhythm being tapped. (By the way, this experiment is fun to try at home if there’s a good “listener” candidate nearby.) </p> <p> "The listener’s job in this game is quite difficult. Over the course of Newton’s experiment, 120 songs were tapped out. Listeners guessed only 2.5 percent of the songs: 3 out of 120. </p> <p> "But here’s what made the result worthy of a dissertation in psychology. Before the listeners guessed the name of the song, Newton asked the tappers to predict the odds that the listeners would guess correctly. They predicted that the odds were 50 percent. </p> <p> "The tappers got their message across 1 time in 40, but they thought they were getting their message across 1 time in 2. Why? </p> <p> "When a tapper taps, she is <em>hearing the song in her head</em>. Go ahead and try it for yourself—tap out “The Star-Spangled Banner.” It’s impossible to avoid hearing the tune in your head. Meanwhile, the listeners can’t hear that tune—all they can hear is a bunch of disconnected taps, like a kind of bizarre Morse Code. </p> <p> "In the experiment, tappers are flabbergasted at how hard the listeners seem to be working to pick up the tune. <em>Isn’t the song obvious?</em> The tappers’ expressions, when a listener guesses “Happy Birthday to You” for “The Star-Spangled Banner,” are priceless: <em>How could you be so stupid?</em> </p> <p> "It’s hard to be a tapper. The problem is that tappers have been given knowledge (the song title) that makes it impossible for them to imagine what it’s like to <em>lack</em> that knowledge. When they’re tapping, they can’t imagine what it’s like for the listeners to hear isolated taps rather than a song. This is the Curse of Knowledge. Once we know something, we find it hard to imagine what it was like not to know it. Our knowledge has “cursed” us. And it becomes difficult for us to share our knowledge with others, because we can’t readily re-create our listeners’ state of mind. </p> <p> "The tapper/listener experiment is reenacted every day across the world. The tappers and listeners are CEOs and frontline employees, teachers and students, politicians and voters, marketers and customers, writers and readers. All of these groups rely on ongoing communication, but, like the tappers and listeners, they suffer from enormous information imbalances. When a CEO discusses “unlocking shareholder value,” there is a tune playing in her head that the employees can’t hear." </p> <footer><cite>Chip Heath and Dan Heath, <a href="https://amzn.to/3viu26j">Made to Stick</a></cite></footer> </blockquote> <p> When you're writing code, you're a <em>tapper</em>. As you're writing the code, you know <em>why</em> you are writing it the way you do, you know what you've already tried that didn't work, the informal requirements that someone told you about over the water cooler, etc. </p> <p> Why should pair or ensemble programming change that? </p> <blockquote> <p> "One of the roles of a PR is to verify that someone who didn't write the new code can understand it. </p> <p> "The constant communication of pair programming can result in code only that pair understands. Does a book with two authors not need an editor?" </p> <footer><cite><a href="https://twitter.com/laurence/status/1448485971289260039">Laurence Gonsalves</a></cite></footer> </blockquote> <p> So, how do you verify that code is readable? </p> <h3 id="77efc0b4e41a4f5597ff6e072187698f"> Readability <a href="#77efc0b4e41a4f5597ff6e072187698f" title="permalink">#</a> </h3> <p> I often forget to remind the reader that discussions like this one, about software productivity, mostly rely on <a href="https://martinfowler.com/bliki/AnecdotalEvidence.html">anecdotal evidence</a>. There's <a href="/2020/05/25/wheres-the-science">little scientific evidence about these topics</a>. The ensuing discussions <a href="/2020/10/12/subjectivity">tend to rely on subjectivity</a>, and so, ultimately, does this one. </p> <p> In <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, I suggest heuristics for writing readable code, but ultimately, the only reliable test of readability that I can think of is simple: </p> <p> Ask someone else to <em>read</em> the code. </p> <p> That's what a code review ought to do. Anyone who took part in writing the code is a <em>tapper</em>. After I've written code, I'm a <em>tapper</em>. I'm in no position to evaluate whether the code I just wrote is readable. </p> <p> You need a <em>listener</em> (or, here: a <em>reader</em>) to evaluate whether or not sufficient information came across. </p> <p> I agree with Dan North that I need other humans to collaborate and calibrate. I just disagree that people who write code are in a position to evaluate whether the code is readable (and thereby can sustain the business in the long run). </p> <h3 id="8655f1951b6a414f82d38435aa317e5c"> Rejection <a href="#8655f1951b6a414f82d38435aa317e5c" title="permalink">#</a> </h3> <p> What happens, then, if I submit a pull request that the reviewer finds unreadable? </p> <p> The reviewer should either suggest improvements or decline the pull request. </p> <p> I can tell from Dan's tweet that he's harbouring a common misconception about the pull request review process: </p> <blockquote> <p> "assuming that an after-the-fact check will always be affirmative" </p> <footer><cite><a href="https://twitter.com/tastapod/status/1448184718122487811">Dan North</a></cite></footer> </blockquote> <p> No, I don't assume that my pull requests always pass muster. That's also the reason that <a href="/2015/01/15/10-tips-for-better-pull-requests">pull requests should be small</a>. They should be small enough that you can afford to have them rejected. </p> <p> I'm currently helping one of my clients with some code. I add some code and send an <a href="/2021/06/21/agile-pull-requests">agile pull request</a>. </p> <p> Several times in the last month, my pull requests have remained unmerged. In none of the cases, actually, have the reviewer outright rejected the pull request. He just started asking questions, then we had a short debate over GitHub, and then I came to the conclusion that I should close the pull request myself. </p> <p> No drama, just feedback. </p> <h3 id="ad0609e523b8401fbab92dc0e90c44d5"> Conclusion <a href="#ad0609e523b8401fbab92dc0e90c44d5" title="permalink">#</a> </h3> <p> How do you verify that code is readable? </p> <p> I can't think of anything better than asking someone else to read the code. </p> <p> Obviously, we shouldn't ask random strangers about readability. We should ask team members to review code. One implication of collective code ownership is that when a team member accepts a pull request, he or she is also taking on the shared responsibility of maintaining that code. As I write in <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, a fundamental criterion for evaluating a pull request is: <em>Will I be okay maintaining this?</em> </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Serendipity-driven development https://blog.ploeh.dk/2021/10/11/serendipity-driven-development 2021-10-11T05:54:00+00:00 Mark Seemann <div id="post"> <p> <em>How much does providence drive thought leadership?</em> </p> <p> I regularly listen to podcasts. Many podcast episodes are structured around an interview with a guest. A common interview technique (and icebreaker, I suppose) is to ask the guest how he or she became a voice in the field that's the topic for the episode. Surprisingly often, the answer is that it's basically a happy coincidence. He or she was young, had no specific plans, but tried a few things until eventually becoming enamoured with a particular topic. </p> <p> That's not just technology podcasts. I also listen to interviews with scientists and artists on a variety of topics. </p> <p> A <em>few</em> people are driven from an early age to study something specific. Most, it seems, are not. I'm no exception. I had a false start as an economist, but was so extremely fortunate that the 1990's were such a boom decade of IT that you could get a job in the field if you could spell HTML. </p> <p> It seems to me that it's a common (Western) experience for a young person to start adult life without much of a plan, but an unrealised responsiveness to certain stimuli. As a young person, you may have a general notion of your own inclinations, so you seek out certain activities and avoid others. Still, you may not really know yourself. </p> <p> I didn't know myself at 18. After <a href="https://en.wikipedia.org/wiki/Gymnasium_(school)">gymnasium</a> (~ high school) in 1989 my best friend started at computer science at the University of Copenhagen. I had no experience with computers and thought it sounded incredibly dry. I wanted to be a rock star or a comic book artist in the French-Belgian style. </p> <p> In order to get an education, though, I started at economics at the University of Copenhagen. Talk about a dry subject. </p> <p> Well, at least I learned game theory, n-dimensional topology, optimal control theory, chaos theory, and some other branches of mathematics, so perhaps the years weren't entirely wasted... </p> <p> Computers weren't on my radar, but I soon realised that it'd be practical to buy a PC in order to write my thesis. </p> <p> So, I bought one and soon found the computer much more interesting than economics. </p> <p> You may not realise that you'll love something until you try it. </p> <h3 id="1909691de650477189ee7d41a49cf22e"> Thought leadership <a href="#1909691de650477189ee7d41a49cf22e" title="permalink">#</a> </h3> <p> I recently wrote <a href="/2021/08/09/am-i-stuck-in-a-local-maximum">an article about the cognitive dissonance I felt</a> when interacting with many of my heroes. The <a href="https://twitter.com/ploeh/status/1424624134030602241">ensuing Twitter discussion</a> was enlightening. </p> <p> Many of my heroes balk at being called heroes or thought leaders, but I agree with <a href="https://hillelwayne.com/">Hillel Wayne</a>: </p> <blockquote> <p> "That's why, incidentally, "thought leaders" have so much weight in our industry. We like to make fun of them, but fact of the matter is that the Thought Leaders are the ones actually trying to communicate their techniques. </p> <p> "(That's why I want to unironically be a Thought Leader)" </p> <footer><cite><a href="https://twitter.com/hillelogram/status/1445435617047990273">Hillel Wayne</a></cite></footer> </blockquote> <p> I've been called a <em>though leader</em> a few times already, and like Hillel Wayne, I gratefully accept the label. </p> <p> There's <a href="/2020/05/25/wheres-the-science">little scientific evidence about what works in software development</a>, and most innovation happens behind closed doors. Thought leaders are those that observe and share the innovation with the rest of the world. </p> <p> I follow though leaders on Twitter, listen to podcasts on which they are guests, and <a href="https://www.goodreads.com/author/show/4383188.Mark_Seemann">read books</a>. </p> <p> I learned a lot from the discussion related to <a href="/2021/08/09/am-i-stuck-in-a-local-maximum">my article about feeling stuck</a>. I feel that I better understand why opposing views exist. Much has to do with context and nuance, two important factors easily lost on Twitter. </p> <p> I also think that personal experience plays a big role. Thought leaders share <a href="https://martinfowler.com/bliki/AnecdotalEvidence.html">anecdotal evidence</a>. As is also the case in science and business, we tend to share our successes. </p> <p> What feels like a success is what resonates with us. </p> <p> It's like the serendipity when you're young and finally encounter something that feels compatible with you. Should we call it serendipity-driven development? </p> <p> A couple of examples may be in order. </p> <h3 id="d4fb5cf60f584d7e8de3e0fcbcb902a7"> Pair programming <a href="#d4fb5cf60f584d7e8de3e0fcbcb902a7" title="permalink">#</a> </h3> <p> While I now have an increased awareness of what motivates other thought leaders, I still often disagree. It wouldn't be unnatural if our personal experiences with particular practices influence our positions. </p> <p> <img src="/content/binary/pair-programming.jpg" alt="Pair programming."> </p> <p> One such example is pair programming. In an interview (sorry, can't remember which) Robert C. Martin told how he found test-driven development dumb until either Kent Beck or Ward Cunningham paired with him to show him the light. Recently, <a href="http://www.exampler.com/">Brian Marick</a> shared a similar experience: </p> <blockquote> <p> "When I first heard of XP, I thought pair programming was the *second* stupidest idea I'd ever heard. The stupidest was everyone working in the same team room (*not* an "open office"). But..." </p> <footer><a href="https://twitter.com/marick/status/1446618423312715779">Brian Marick</a></footer> </blockquote> <p> This seems to be a common experience with pair programming. Most people dislike it until they have actually tried it. </p> <p> Well, I've tried both pair programming and ensemble (AKA mob) programming, and I don't <em>like</em> it. </p> <p> That's all: It's my <em>preference</em> - not any sort of objective truth. What little scientific evidence we can find in our field does seem to indicate that pair programming is efficient. In my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> I've put aside my dislike to instead endorse pair and ensemble programming as something you should consider. </p> <p> There's enough evidence (anecdotal and otherwise) that it works well for many people, so give it a try. </p> <p> I also use it myself. While I find it exhausting, I find ensemble programming incredibly well-suited to knowledge transfer. I've used it to great success when teaching development organisations new ways of doing things. </p> <p> Even with the nicest people in the room, however, the process drains me. One reason is probably that I've a strong introvert side to my personality. </p> <p> Another perspective to consider is the role you assume. </p> <p> A common theme when people share stories of how they saw the light of pair programming is that they learned it from luminaries. If Kent Beck or Ward Cunningham personally tutors you, it's easy to see how it could feel like a revelation. </p> <p> On the other hand, <a href="https://en.wikipedia.org/wiki/Survivorship_bias">survivorship bias</a> could be at work. Perhaps Kent Beck showed pair programming and test-driven development to many people who never caught the bug, and thus never discussed it in public. </p> <p> In my own experience, I mostly taught myself test-driven development long before I tried pair programming, and I'd heard about pair programming long before I tried it. When I did try it, I wasn't the person being taught. I was in the role of the teacher. </p> <p> Teaching is both a satisfying and exhausting activity. I do consider myself a teacher of sorts, but I prefer to write. Whenever I've taught a workshop, given a lecture, or consulted, I'm always left happy but exhausted. It's really hard work. </p> <p> So is pair programming, in my experience. Efficient, most likely, but hard work. I can't muster much enthusiasm about it. </p> <h3 id="4b17192456614ca28a4e69cb5f86e23b"> REST <a href="#4b17192456614ca28a4e69cb5f86e23b" title="permalink">#</a> </h3> <p> Another topic about which I regularly disagree with others is <a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a>. Just try to find some of my articles <a href="/tags/#REST-ref">tagged REST</a> and read the comments. </p> <p> For the record, the crowd who disagrees with me is a completely different set of people than those with whom I disagree about pair programming and other agile practices. </p> <p> The people who disagree with me about REST may be right, and I could be wrong. My views on REST are strongly influenced by early experience. Do be aware of the pattern. </p> <p> In early 2012 a client asked for my help designing a stable API. The customer didn't ask me to design a REST API - in fact, I think he had a <a href="https://en.wikipedia.org/wiki/SOAP">SOAP</a> API in mind, but he was open to other options. One requirement was clear, though: The API had to be exceptionally stable and backwards compatible. There was a reason for this. </p> <p> My customer's business was to provide a consumer-grade online service. They were currently talking to a hardware producer who'd include support for the service in consumer hardware. Imagine thousands (perhaps millions) of devices sitting in people's homes, using the online service via the API we were about to design. </p> <p> Even if the hardware producer were to enable firmware upgrades of the devices, there'd be no way we could roll out new versions of client software in a controlled way. This meant that backwards compatibility was a top priority. </p> <p> I'd recently learned enough about REST to see the opportunity, so I suggested it as a principle for designing APIs that could evolve without breaking backwards compatibility. </p> <p> The resulting REST API was a success, and I worked with that client for many years on other projects. </p> <p> This experience clearly shaped my view on REST. To me, the major benefit of REST is the ability to design evolvable APIs without breaking changes. It does work best, however, if you design <a href="https://martinfowler.com/articles/richardsonMaturityModel.html">level 3 REST APIs</a>. </p> <p> People use HTTP APIs for all sorts of other reasons. Perhaps the driving factor isn't evolvability, but rather interoperability. Perhaps they're developing <a href="https://samnewman.io/patterns/architectural/bff/">backends for frontends</a> or APIs strictly for internal use in an organisation. In some scenarios you can easier schedule updates of clients to coincide with updates to the API, in which case backwards compatibility is less of a concern. </p> <p> Another concern about API design is <a href="https://thoughtbot.com/blog/who-is-empowered-by-your-design">who's empowered by your design</a>. It seems fair to say that a level 2 REST API is an easier sell. To many client developers, that's all they've ever encountered - they've never seen a level 3 REST API. </p> <p> I readily admit that a level 3 REST API puts an additional up-front burden on client developers. Such a design is a long game. If the API is active for many years, such investments are likely to pay off, while it may not be worthwhile in the short term. It could even hurt initial adoption, so it's not a one-size-fits-all architectural choice. </p> <p> In the context of thought leadership, however, my point is that I acknowledge that my view on REST, too, is flavoured by initial personal success. </p> <h3 id="f6e7da07a61340ef9f1617cb5fb19071"> Conclusion <a href="#f6e7da07a61340ef9f1617cb5fb19071" title="permalink">#</a> </h3> <p> I think it's natural to latch on to certain practices via serendipity, You go through life without being aware of a thing that turns out to be highly compatible with your preferences in a given context. Until you one day <em>do</em> encounter it, and it changes your life. </p> <p> I consider this only human. It's certainly happened to me multiple times, and I'd be surprised if it doesn't happen to others. </p> <p> Perhaps the people extolling the virtues of pair programming had great initial experiences that they've managed to carry forward. For me, the experience has been another. </p> <p> Likewise, I had an initial positive experience with REST that surely influenced my position on its virtues. Other people could have had a negative experience, and naturally protest against my ideas. There's nothing wrong with that. </p> <blockquote> <p> "Only a crisis - actual or perceived - produces real change. When that crisis occurs, the actions that are taken depend on the ideas that are lying around. That, I believe, is our basic function: to develop alternatives to existing policies, to keep them alive and available until the politically impossible becomes the politically inevitable" </p> <footer><a href="https://amzn.to/3BsIqLG">Milton Friedman</a></footer> </blockquote> <p> Thought leadership strikes me as similar to Friedman's ideas on policy alternatives. I don't see my role as an <em>enforcer</em> of ideas. I write in order to keep certain ideas alive, in the hope that one day, someone picks them up and uses them. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Reader as a contravariant functor https://blog.ploeh.dk/2021/10/04/reader-as-a-contravariant-functor 2021-10-04T05:47:00+00:00 Mark Seemann <div id="post"> <p> <em>Any function gives rise to a contravariant functor. An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction. In the <a href="/2021/09/06/the-command-handler-contravariant-functor">first example article</a>, you saw how the Command Handler pattern gives rise to a contravariant functor. <a href="/2021/09/09/the-specification-contravariant-functor">The next article</a> gave another example based on predicates. </p> <p> In the <a href="/2021/09/02/contravariant-functors">overview article</a> I also mentioned that equivalence and comparison form contravariant functors. Each can be described with an interface, or just function syntax. Let's put them in a table to compare them: </p> <p> <table border="1"> <thead> <tr> <th><em>Name</em></th> <th><em>C# method signature</em></th> <th><em>C# delegate(s)</em></th> <th><em>Haskell type(s)</em></th> </tr> </thead> <tbody> <tr> <td>Command Handler</td> <td><code><span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(TCommand&nbsp;<span style="color:#1f377f;">command</span>);</code></td> <td><code>Action&lt;TCommand&gt;</code></td> <td><code>a -&gt; ()</code><br/><code>a -&gt; IO ()</code></td> </tr> <tr> <td>Specification</td> <td><code><span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(T&nbsp;<span style="color:#1f377f;">candidate</span>);</code></td> <td><code>Predicate&lt;T&gt;</code><br/><code>Func&lt;T, bool&gt;</code></td> <td><code>a -&gt; Bool</code></td> </tr> <tr> <td>Equivalence</td> <td><code><span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(T&nbsp;<span style="color:#1f377f;">x</span>,&nbsp;T&nbsp;<span style="color:#1f377f;">y</span>);</code></td> <td><code>Func&lt;T, T, bool&gt;</code></td> <td><code>a -&gt; a -&gt; Bool</code></td> </tr> <tr> <td>Comparison</td> <td><code><span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">Compare</span>(T&nbsp;<span style="color:#1f377f;">x</span>,&nbsp;T&nbsp;<span style="color:#1f377f;">y</span>);</code></td> <td><code>Func&lt;T, T, int&gt;</code></td> <td><code>a -&gt; a -&gt; Ordering</code></td> </tr> </tbody> </table> </p> <p> In some cases, there's more than one possible representation. For example, in C# <a href="https://docs.microsoft.com/dotnet/api/system.predicate-1">Predicate</a> is isomorphic to <code>Func&lt;T, bool&gt;</code>. When it comes to the <a href="https://www.haskell.org">Haskell</a> representation of a Command Handler, the 'direct' translation of <code>Action&lt;T&gt;</code> is <code>a -&gt; ()</code>. In (Safe) Haskell, however, a function with that type is always a no-op. More realistically, a 'handler' function would have the type <code>a -&gt; IO ()</code> in order to allow side effects to happen. </p> <p> Do you notice a pattern? </p> <h3 id="920ac139cb1449789dac402d3e05c368"> Input variance <a href="#920ac139cb1449789dac402d3e05c368" title="permalink">#</a> </h3> <p> There's a pattern emerging from the above table. Notice that in all the examples, the function types are generic (AKA <em>parametrically polymorphic</em>) in their <em>input</em> types. </p> <p> This turns out to be part of a general rule. The actual rule is a little more complicated than that. I'll recommend <a href="https://reasonablypolymorphic.com">Sandy Maguire</a>'s <a href="https://www.goodreads.com/review/show/3406773267">excellent</a> book <a href="https://thinkingwithtypes.com">Thinking with Types</a> if you're interested in the details. </p> <p> For first-order functions, you can pick and fix <em>any</em> type as the return type and let the input type(s) vary: that function will give rise to a contravariant functor. </p> <p> In the above table, various handlers fix <code>void</code> (which is <a href="/2018/01/15/unit-isomorphisms">isomorphic to <em>unit</em></a> (<code>()</code>) as the output type and let the input type vary. Both Specification and Equivalence fix <code>bool</code> as the output type, and Comparison fix <code>int</code> (or, in Haskell, the more sane type <code>Ordering</code>), and allow the input type to vary. </p> <p> You can pick any other type. If you fix it as <em>the</em> output type for a function and let the input vary, you have the basis for a contravariant functor. </p> <h3 id="11651dbe49d04a6989c45fc52744ebf8"> Reader <a href="#11651dbe49d04a6989c45fc52744ebf8" title="permalink">#</a> </h3> <p> Consider this <code>IReader</code> interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReader</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;<span style="color:#74531f;">Run</span>(R&nbsp;<span style="color:#1f377f;">environment</span>); }</pre> </p> <p> If you fix the environment type <code>R</code> and let the output type <code>A</code> vary, <a href="/2021/08/30/the-reader-functor">you have a (covariant) functor</a>. If, on the other hand, you fix the <em>output</em> type <code>A</code> and allow the input type <code>R</code> to vary, you can have yourself a contravariant functor: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IReader&lt;R1,&nbsp;A&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">R1</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IReader&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">reader</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;R1,&nbsp;R&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;FuncReader&lt;R1,&nbsp;A&gt;(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;reader.Run(selector(r))); }</pre> </p> <p> As an example, you may have this (rather unwarranted) interface implementation: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">MinutesReader</span>&nbsp;:&nbsp;IReader&lt;<span style="color:blue;">int</span>,&nbsp;TimeSpan&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;TimeSpan&nbsp;<span style="color:#74531f;">Run</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">environment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;TimeSpan.FromMinutes(environment); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> You can fix the output type to <code>TimeSpan</code> and let the input type vary using the <code>ContraMap</code> functions: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">WrappedContravariantExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;<span style="color:blue;">int</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;MinutesReader(); &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">projected</span>&nbsp;=&nbsp;r.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;<span style="color:blue;">int</span>.Parse(s)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;TimeSpan(0,&nbsp;21,&nbsp;0),&nbsp;projected.Run(<span style="color:#a31515;">&quot;21&quot;</span>)); }</pre> </p> <p> When you <code>Run</code> the <code>projected</code> reader with the input string <code>"21"</code>, the <code>ContraMap</code> function first calls the <code>selector</code>, which (in this case) parses <code>"21"</code> to the integer <code>21</code>. It then calls <code>Run</code> on the 'original' <code>reader</code> with the value <code>21</code>. Since the 'original' <code>reader</code> is a <code>MinutesReader</code>, the output is a <code>TimeSpan</code> value that represents 21 minutes. </p> <h3 id="d147d424c6de412d9ad83cf659812ef6"> Raw functions <a href="#d147d424c6de412d9ad83cf659812ef6" title="permalink">#</a> </h3> <p> As was also the case when I introduced the Reader (covariant) functor, the <code>IReader</code> interface is just a teaching device. You don't need the interface in order to turn first-order functions into contravariant functors. It works on raw functions too: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;R1,&nbsp;A&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">R1</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">func</span>,&nbsp;Func&lt;R1,&nbsp;R&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;func(selector(r)); }</pre> </p> <p> In the following I'm going to dispense with the <code>IReader</code> interface and instead work with raw functions. </p> <h3 id="ad09f6dd9b3542b4ba8c01a01baa6afa"> Identity law <a href="#ad09f6dd9b3542b4ba8c01a01baa6afa" title="permalink">#</a> </h3> <p> A <code>ContraMap</code> method with the right signature isn't enough to be a contravariant functor. It must also obey the contravariant functor laws. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the identity law for functions. In this article, you'll see parametrised tests written with <a href="https://xunit.net">xUnit.net</a>. First, the identity law: </p> <p> <pre>[Theory] [InlineData(42)] [InlineData(1337)] [InlineData(2112)] [InlineData(90125)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ContravariantIdentityLaw</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;i.ToString(); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;f.ContraMap((<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">i</span>)&nbsp;=&gt;&nbsp;i); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(f(input),&nbsp;actual(input)); }</pre> </p> <p> Here I'm using the <code>(int i) =&gt; i</code> lambda expression as the identity function. As usual, you can't easily compare functions for equality, so you'll have to call them to verify that they produce the same output, which they do. </p> <h3 id="2e1d05c3d61c4773820dbbaec5967565"> Composition law <a href="#2e1d05c3d61c4773820dbbaec5967565" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>ContraMap</code> obeys the composition law for contravariant functors: </p> <p> <pre>[Theory] [InlineData(4.2)] [InlineData(13.37)] [InlineData(21.12)] [InlineData(901.25)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ContravariantCompositionLaw</span>(<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;TimeSpan.FromSeconds(i); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TimeSpan,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;ts.ToString(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h.ContraMap((<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">d</span>)&nbsp;=&gt;&nbsp;g(f(d)))(input), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h.ContraMap(g).ContraMap(f)(input)); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Once more, you can't directly compare methods for equality, so instead you have to invoke both compositions to verify that they return the same <code>int</code> value. </p> <p> They do. </p> <h3 id="392a90e5e3204d459dae673d23be92e1"> Isomorphisms <a href="#392a90e5e3204d459dae673d23be92e1" title="permalink">#</a> </h3> <p> Now that we understand that any first-order function is contravariant, we can see that the previous examples of predicates, handlers, comparisons, and equivalences are really just special cases of the Reader contravariant functor. </p> <p> For example, <code>Predicate&lt;T&gt;</code> is trivially isomorphic to <code>Func&lt;T, bool&gt;</code>. Still, it might be worthwhile to flesh out how other translations might work: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#74531f;">AsSpecification</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;Predicate&lt;T&gt;&nbsp;<span style="color:#1f377f;">predicate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;DelegateSpecificationAdapter&lt;T&gt;(predicate); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#74531f;">AsSpecification</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;T,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">predicate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;DelegateSpecificationAdapter&lt;T&gt;(predicate); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">DelegateSpecificationAdapter</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;:&nbsp;ISpecification&lt;T&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Predicate&lt;T&gt;&nbsp;predicate; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">DelegateSpecificationAdapter</span>(Predicate&lt;T&gt;&nbsp;<span style="color:#1f377f;">predicate</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.predicate&nbsp;=&nbsp;predicate; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">DelegateSpecificationAdapter</span>(Func&lt;T,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">predicate</span>)&nbsp;: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>((Predicate&lt;T&gt;)(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;predicate(x))) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(T&nbsp;<span style="color:#1f377f;">candidate</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;predicate(candidate); &nbsp;&nbsp;&nbsp;&nbsp;} } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Predicate&lt;T&gt;&nbsp;<span style="color:#74531f;">AsPredicate</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#1f377f;">specification</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">candidate</span>&nbsp;=&gt;&nbsp;specification.IsSatisfiedBy(candidate); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;T, bool&gt;&nbsp;<span style="color:#74531f;">AsFunc</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#1f377f;">specification</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">candidate</span>&nbsp;=&gt;&nbsp;specification.IsSatisfiedBy(candidate); }</pre> </p> <p> Above are conversions between <code>ISpecification&lt;T&gt;</code> on the one hand, and <code>Predicate&lt;T&gt;</code> and <code>Func&lt;T, bool&gt;</code> on the other. Not shown are the conversions between <code>Predicate&lt;T&gt;</code> and <code>Func&lt;T, bool&gt;</code>, since they are already built into C#. </p> <p> Most saliently in this context is that it's possible to convert both <code>ISpecification&lt;T&gt;</code> and <code>Predicate&lt;T&gt;</code> to <code>Func&lt;T, bool&gt;</code>, and <code>Func&lt;T, bool&gt;</code> to <code>ISpecification&lt;T&gt;</code> or <code>Predicate&lt;T&gt;</code> without any loss of information. Specifications and predicates are isomorphic to an open constructed <code>Func</code> - that is, a Reader. </p> <p> I'll leave the other isomorphisms as exercises, with the following hints: </p> <ul> <li>You can only convert an <code>ICommandHandler&lt;T&gt;</code> to a <code>Func</code> if you introduce a <code>Unit</code> value, but you could also try to use <code>Action&lt;T&gt;</code>.</li> <li>For Equivalence, you'll need to translate the two input arguments to a single object or value.</li> <li>The same goes for Comparison.</li> </ul> <p> All the contravariant functor examples shown so far in this article series are isomorphic to the Reader contravariant functor. </p> <p> Particularly, this also explains why <a href="/2021/09/27/the-equivalence-contravariant-functor">it was possible to make <code>IEqualityComparer.GetHashCode</code> contravariant</a>. </p> <h3 id="fa845ae308634182bf6e82298205c9a8"> Haskell <a href="#fa845ae308634182bf6e82298205c9a8" title="permalink">#</a> </h3> <p> The Haskell <em>base</em> package comes with a <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">Contravariant type class</a> and various instances. </p> <p> In order to replicate the above <code>MinutesReader</code> example, we can start by implementing a function with equivalent behaviour: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; minutes m = secondsToDiffTime (60 * m) Prelude Data.Functor.Contravariant Data.Time&gt; :t minutes minutes :: Integer -&gt; DiffTime</pre> </p> <p> As GHCi reports, the <code>minutes</code> function has the type <code>Integer -&gt; DiffTime</code> (<code>DiffTime</code> corresponds to .NET's <code>TimeSpan</code>). </p> <p> The above C# example contramaps a <code>MinutesReader</code> with a function that parses a <code>string</code> to an <code>int</code>. In Haskell, we can use the built-in <code>read</code> function to equivalent effect. </p> <p> Here's where Haskell gets a little odd. In order to fit the <code>Contravariant</code> type class, we need to flip the type arguments of a function. A normal function is usually written as having the type <code>a -&gt; b</code>, but we can also write it as the type <code>(-&gt;) a b</code>. With this notation, <code>minutes</code> has the type <code>(-&gt;) Integer DiffTime</code>. </p> <p> In order to make <code>minutes</code> a contravariant instance, we need to fix <code>DiffTime</code> and let the input vary. What we'd like to have is something like this: <code>(-&gt;) a DiffTime</code>. Alas, that's not how you define a legal type class instance in Haskell. We have to flip the types around so that we can partially apply the type. The built-in <code>newtype Op</code> does that: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; :t Op minutes Op minutes :: Op DiffTime Integer</pre> </p> <p> Since the general, partially applied type <code>Op a</code> is a <code>Contravariant</code> instance, it follows that the specific type <code>Op DiffTime</code> is. This means that we can <code>contramap</code> <code>Op minutes</code> with <code>read</code>: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; :t contramap read (Op minutes) contramap read (Op minutes) :: Op DiffTime String</pre> </p> <p> Notice that this maps an <code>Op DiffTime Integer</code> to an <code>Op DiffTime String</code>. </p> <p> How do you use it? </p> <p> You can retrieve the function wrapped in <code>Op</code> with the <code>getOp</code> function: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; :t getOp (contramap read (Op minutes)) getOp (contramap read (Op minutes)) :: String -&gt; DiffTime</pre> </p> <p> As you can tell, this expression indicates a <code>String -&gt; DiffTime</code> function. This means that if you call it with a string representation of an integer, you should get a <code>DiffTime</code> value back: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; getOp (contramap read (Op minutes)) "21" 1260s</pre> </p> <p> As usual, this is way too complicated to be immediately useful, but it once again demonstrates that contravariant functors are ubiquitous. </p> <h3 id="c5952616e8b24528900fcdc9b2b75535"> Conclusion <a href="#c5952616e8b24528900fcdc9b2b75535" title="permalink">#</a> </h3> <p> Normal first-order functions give rise to contravariant functors. With sufficiently tinted glasses, <a href="/2018/01/08/software-design-isomorphisms">most programming constructs look like functions</a>. To me, at least, this indicates that a contravariant functor is a fundamental abstraction in programming. </p> <p> This result looks quite abstract, but <a href="/2021/11/29/postels-law-as-a-profunctor">future articles</a> will build on it to arrive at a (to me) fascinating conclusion. Until then, though... </p> <p> <strong>Next:</strong> <a href="/2021/10/25/functor-variance-compared-to-cs-notion-of-variance">Functor variance compared to C#'s notion of variance</a>. </p> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. The Equivalence contravariant functor https://blog.ploeh.dk/2021/09/27/the-equivalence-contravariant-functor 2021-09-27T06:08:00+00:00 Mark Seemann <div id="post"> <p> <em>An introduction to the Equivalence contravariant functor for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction. In previous articles, you saw examples of <a href="/2021/09/06/the-command-handler-contravariant-functor">the Command Handler</a> and <a href="/2021/09/09/the-specification-contravariant-functor">Specification</a> contravariant functors. This article presents another example. </p> <p> In <a href="/2021/09/20/keep-ids-internal-with-rest">a recent article</a> I described how I experimented with removing the <code>id</code> property from a JSON representation in a REST API. I also mentioned that doing that made one test fail. In this article you'll see the failing test and how the Equivalence contravariant functor can improve the situation. </p> <h3 id="be01e1b437a94b2689f5fdd3a68ae33f"> Baseline <a href="#be01e1b437a94b2689f5fdd3a68ae33f" title="permalink">#</a> </h3> <p> Before I made the change, the test in question looked like this: </p> <p> <pre>[Theory] [InlineData(1049,&nbsp;19,&nbsp;00,&nbsp;<span style="color:#a31515;">&quot;juliad@example.net&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Julia&nbsp;Domna&quot;</span>,&nbsp;5)] [InlineData(1130,&nbsp;18,&nbsp;15,&nbsp;<span style="color:#a31515;">&quot;x@example.com&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Xenia&nbsp;Ng&quot;</span>,&nbsp;9)] [InlineData(&nbsp;956,&nbsp;16,&nbsp;55,&nbsp;<span style="color:#a31515;">&quot;kite@example.edu&quot;</span>,&nbsp;<span style="color:blue;">null</span>,&nbsp;2)] [InlineData(&nbsp;433,&nbsp;17,&nbsp;30,&nbsp;<span style="color:#a31515;">&quot;shli@example.org&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Shanghai&nbsp;Li&quot;</span>,&nbsp;5)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">PostValidReservationWhenDatabaseIsEmpty</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">days</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">hours</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">minutes</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">email</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">name</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantity</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">at</span>&nbsp;=&nbsp;DateTime.Now.Date&nbsp;+&nbsp;<span style="color:blue;">new</span>&nbsp;TimeSpan(days,&nbsp;hours,&nbsp;minutes,&nbsp;0); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">db</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;FakeDatabase(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationsController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;SystemClock(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;InMemoryRestaurantDatabase(Grandfather.Restaurant), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">dto</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationDto &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;<span style="color:#a31515;">&quot;B50DF5B1-F484-4D99-88F9-1915087AF568&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;At&nbsp;=&nbsp;at.ToString(<span style="color:#a31515;">&quot;O&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;email, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;=&nbsp;name, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;quantity &nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;sut.Post(dto); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Guid.Parse(dto.Id), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Email(email), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Name(name&nbsp;??&nbsp;<span style="color:#a31515;">&quot;&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;quantity); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Contains(expected,&nbsp;db.Grandfather); }</pre> </p> <p> You can find this test in the code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, although I've slightly simplified the initialisation of <code>expected</code> since I froze the code for the manuscript. I've already discussed this particular test in the articles <a href="/2020/12/07/branching-tests">Branching tests</a>, <a href="/2021/01/11/waiting-to-happen">Waiting to happen</a>, and <a href="/2021/01/18/parametrised-test-primitive-obsession-code-smell">Parametrised test primitive obsession code smell</a>. It's the gift that keeps giving. </p> <p> It's a <a href="/2019/04/01/an-example-of-state-based-testing-in-c">state-based integration test</a> that verifies the state of the <code>FakeDatabase</code> after 'posting' a reservation to 'the REST API'. I'm using quotes because the test doesn't really perform an HTTP POST request (it's not <a href="/2021/01/25/self-hosted-integration-tests-in-aspnet">a self-hosted integration test</a>). Rather, it directly calls the <code>Post</code> method on the <code>sut</code>. In the assertion phase, it uses Back Door Manipulation (as <a href="http://bit.ly/xunitpatterns">xUnit Test Patterns</a> terms it) to verify the state of the <a href="http://xunitpatterns.com/Fake%20Object.html">Fake</a> <code>db</code>. </p> <p> If you're wondering about the <code>Grandfather</code> property, <a href="/2020/11/16/redirect-legacy-urls">it represents the original restaurant that was grandfathered in</a> when I expanded the REST API to a multi-tenant service. </p> <p> Notice, particularly, the use of <code>dto.Id</code> when defining the <code>expected</code> reservation. </p> <h3 id="be8ae690e33a4e7fb3b5d5f15d6ddce9"> Brittle assertion <a href="#be8ae690e33a4e7fb3b5d5f15d6ddce9" title="permalink">#</a> </h3> <p> When I <a href="/2021/09/20/keep-ids-internal-with-rest">made the <code>Id</code> property <code>internal</code></a>, this test no longer compiled. I had to delete the assignment of <code>Id</code>, which also meant that I couldn't use a deterministic <code>Guid</code> to define the <code>expected</code> value. While I could create an arbitrary <code>Guid</code>, that would never pass the test, since the <code>Post</code> method also generates a new <code>Guid</code>. </p> <p> In order to <a href="/2019/10/21/a-red-green-refactor-checklist">get to green</a> as quickly as possible, I rewrote the assertion: </p> <p> <pre>Assert.Contains( &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;&nbsp;&nbsp;DateTime.Parse(dto.At,&nbsp;CultureInfo.InvariantCulture)&nbsp;==&nbsp;r.At &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span style="color:blue;">new</span>&nbsp;Email(dto.Email)&nbsp;==&nbsp;r.Email &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span style="color:blue;">new</span>&nbsp;Name(dto.Name&nbsp;??&nbsp;<span style="color:#a31515;">&quot;&quot;</span>)&nbsp;==&nbsp;r.Name &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;dto.Quantity&nbsp;==&nbsp;r.Quantity);</pre> </p> <p> This passed the test so that I could move on. It may even be the simplest thing that could possibly work, but it's brittle and noisy. </p> <p> It's brittle because it explicitly considers the four properties <code>At</code>, <code>Email</code>, <code>Name</code>, and <code>Quantity</code> of the <code>Reservation</code> class. What happens if you add a new property to <code>Reservation</code>? What happens if you have similar assertions scattered over the code base? </p> <p> This is one reason that <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> also applies to unit tests. You want to have as few places as possible that you have to edit when making changes. Otherwise, the risk increases that you forget one or more. </p> <p> Not only is the assertion brittle - it's also noisy, because it's hard to read. There's parsing, null coalescing and object initialisation going on in those four lines of Boolean operations. Perhaps it'd be better to extract a well-named helper method, but while I'm often in favour of doing that, I'm also a little concerned that too many ad-hoc helper methods obscure something essential. After all: </p> <blockquote> <p> "Abstraction is the elimination of the irrelevant and the amplification of the essential" </p> <footer><cite>Robert C. Martin, <a href="http://amzn.to/19W4JHk">APPP</a></cite></footer> </blockquote> <p> The hardest part of abstraction is striking the right balance. Does a well-named helper method effectively communicate the essentials while eliminating <em>only</em> the irrelevant. While I favour good names over bad names, I'm also aware that <a href="/2020/11/23/good-names-are-skin-deep">good names are skin-deep</a>. If I can draw on a universal abstraction rather than coming up with an ad-hoc name, I prefer doing that. </p> <p> Which universal abstraction might be useful in this situation? </p> <h3 id="724d8609add4401cae58a14c259c5698"> Relaxed comparison <a href="#724d8609add4401cae58a14c259c5698" title="permalink">#</a> </h3> <p> The baseline version of the test relied on the structural equality of the <code>Reservation</code> class: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>?&nbsp;<span style="color:#1f377f;">obj</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id.Equals(reservation.Id)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;At&nbsp;==&nbsp;reservation.At&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;Email&gt;.Default.Equals(Email,&nbsp;reservation.Email)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;Name&gt;.Default.Equals(Name,&nbsp;reservation.Name)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;==&nbsp;reservation.Quantity; }</pre> </p> <p> This implementation was auto-generated by a Visual Studio <em>Quick Action</em>. From C# 9, I could also have made <code>Reservation</code> a <a href="https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/record">record</a>, in which case the compiler would be taking care of implementing <code>Equals</code>. </p> <p> The <code>Reservation</code> class already defines the canonical way to compare two reservations for equality. Why can't we use that? </p> <p> The <code>PostValidReservationWhenDatabaseIsEmpty</code> test can no longer use the <code>Reservation</code> class' structural equality because it doesn't know what the <code>Id</code> is going to be. </p> <p> One way to address this problem is to inject a hypothetical <code>IGuidGenerator</code> dependency into <code>ReservationsController</code>. I consider this a valid alternative, since the Controller already takes an <code>IClock</code> dependency. I might be inclined towards such a course of action <a href="/2020/03/23/repeatable-execution">for other reasons</a>, but here I wanted to explore other options. </p> <p> Can we somehow reuse the <code>Equals</code> implementation of <code>Reservation</code>, but relax its behaviour so that it doesn't consider the <code>Id</code>? </p> <p> This would be <a href="https://docs.microsoft.com/archive/msdn-magazine/2010/october/msdn-magazine-the-working-programmer-multiparadigmatic-net-part-2">what Ted Neward called <em>negative variability</em></a> - the ability to subtract from an existing feature. As he implied in 2010, normal programming languages don't have that capability. That strikes me as true in 2021 as well. </p> <p> The best we can hope for, then, is to put the required custom comparison somewhere central, so that at least it's not scattered across the entire code base. Since the test uses <a href="https://xunit.net">xUnit.net</a>, a class that implements <code>IEqualityComparer&lt;Reservation&gt;</code> sounds like just the right solution. </p> <p> This is definitely doable, but it's odd having to define a custom equality comparer for a class that already has structural equality. In the context of the <code>PostValidReservationWhenDatabaseIsEmpty</code> test, we understand the reason, but for a future team member who may encounter the class out of context, it might be confusing. </p> <p> Are there other options? </p> <h3 id="df0297c4c0274368843e9e0f5bb98cba"> Reuse <a href="#df0297c4c0274368843e9e0f5bb98cba" title="permalink">#</a> </h3> <p> It turns out that, by lucky accident, the code base already contains an equality comparer that almost fits: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ReservationDtoComparer</span>&nbsp;:&nbsp;IEqualityComparer&lt;ReservationDto&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(ReservationDto?&nbsp;<span style="color:#1f377f;">x</span>,&nbsp;ReservationDto?&nbsp;<span style="color:#1f377f;">y</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">datesAreEqual</span>&nbsp;=&nbsp;Equals(x?.At,&nbsp;y?.At); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!datesAreEqual&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime.TryParse(x?.At,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">xDate</span>)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime.TryParse(y?.At,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">yDate</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datesAreEqual&nbsp;=&nbsp;Equals(xDate,&nbsp;yDate); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;datesAreEqual &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;Equals(x?.Email,&nbsp;y?.Email) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;Equals(x?.Name,&nbsp;y?.Name) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;Equals(x?.Quantity,&nbsp;y?.Quantity); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>(ReservationDto&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">dateHash</span>&nbsp;=&nbsp;obj.At?.GetHashCode(StringComparison.InvariantCulture); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(DateTime.TryParse(obj.At,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">dt</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dateHash&nbsp;=&nbsp;dt.GetHashCode(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;HashCode.Combine(dateHash,&nbsp;obj.Email,&nbsp;obj.Name,&nbsp;obj.Quantity); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This class already compares two reservations' dates, emails, names, and quantities, while ignoring any IDs. Just what we need? </p> <p> There's only one problem. <code>ReservationDtoComparer</code> compares <code>ReservationDto</code> objects - not <code>Reservation</code> objects. </p> <p> Would it be possible to somehow, on the spot, without writing a new class, transform <code>ReservationDtoComparer</code> to an <code>IEqualityComparer&lt;Reservation&gt;</code>? </p> <p> Well, yes it is. </p> <h3 id="affeb3f683624666a9c1bb3b0bae342a"> Contravariant functor <a href="#affeb3f683624666a9c1bb3b0bae342a" title="permalink">#</a> </h3> <p> We can contramap an <code>IEqualityComparer&lt;ReservationDto&gt;</code> to a <code>IEqualityComparer&lt;Reservation&gt;</code> because <em>equivalence</em> gives rise to a contravariant functor. </p> <p> In order to enable contravariant mapping, you must add a <code>ContraMap</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Equivalance</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEqualityComparer&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IEqualityComparer&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>)&nbsp;<span style="color:blue;">where</span>&nbsp;T&nbsp;:&nbsp;<span style="color:blue;">notnull</span> &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ContraMapComparer&lt;T,&nbsp;T1&gt;(source,&nbsp;selector); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ContraMapComparer</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;&nbsp;:&nbsp;IEqualityComparer&lt;T1&gt;&nbsp;<span style="color:blue;">where</span>&nbsp;T&nbsp;:&nbsp;<span style="color:blue;">notnull</span> &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IEqualityComparer&lt;T&gt;&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ContraMapComparer</span>(IEqualityComparer&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.source&nbsp;=&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.selector&nbsp;=&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>([AllowNull]&nbsp;T1&nbsp;<span style="color:#1f377f;">x</span>,&nbsp;[AllowNull]&nbsp;T1&nbsp;<span style="color:#1f377f;">y</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(x&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>&nbsp;&amp;&amp;&nbsp;y&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">true</span>; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(x&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>&nbsp;||&nbsp;y&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">false</span>; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.Equals(selector(x),&nbsp;selector(y)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>(T1&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.GetHashCode(selector(obj)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Since the <code>IEqualityComparer&lt;T&gt;</code> interface defines <em>two</em> methods, the <code>selector</code> must contramap the behaviour of both <code>Equals</code> and <code>GetHashCode</code>. Fortunately, that's possible. </p> <p> Notice that, as explained in the overview article, in order to map from an <code>IEqualityComparer&lt;T&gt;</code> to an <code>IEqualityComparer&lt;T1&gt;</code>, the <code>selector</code> has to go the other way: from <code>T1</code> to <code>T</code>. How this is possible will become more apparent with an example, which will follow later in the article. </p> <h3 id="911357268ea14f09ac03bac6a781333e"> Identity law <a href="#911357268ea14f09ac03bac6a781333e" title="permalink">#</a> </h3> <p> A <code>ContraMap</code> method with the right signature isn't enough to be a contravariant functor. It must also obey the contravariant functor laws. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the identity law for the <code>IEqualityComparer&lt;T&gt;</code> interface. In this article, you'll see parametrised tests written with xUnit.net. First, the identity law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;1,&nbsp;<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;1)] [InlineData(<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;2,&nbsp;<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;2)] [InlineData(<span style="color:#a31515;">&quot;19:00&quot;</span>,&nbsp;1,&nbsp;<span style="color:#a31515;">&quot;19:00&quot;</span>,&nbsp;1)] [InlineData(<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;1,&nbsp;<span style="color:#a31515;">&quot;19:00&quot;</span>,&nbsp;1)] [InlineData(<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;2,&nbsp;<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;1)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">time1</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">size1</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">time2</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">size2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDtoComparer(); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;IEqualityComparer&lt;TimeDto&gt;?&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.ContraMap&lt;TimeDto,&nbsp;TimeDto&gt;(id); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">dto1</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDto&nbsp;{&nbsp;Time&nbsp;=&nbsp;time1,&nbsp;MaximumPartySize&nbsp;=&nbsp;size1&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">dto2</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDto&nbsp;{&nbsp;Time&nbsp;=&nbsp;time2,&nbsp;MaximumPartySize&nbsp;=&nbsp;size2&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(sut.Equals(dto1,&nbsp;dto2),&nbsp;actual.Equals(dto1,&nbsp;dto2)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(sut.GetHashCode(dto1),&nbsp;actual.GetHashCode(dto1)); }</pre> </p> <p> In order to observe that the two comparers have identical behaviours, the test must invoke both the <code>Equals</code> and the <code>GetHashCode</code> methods on both <code>sut</code> and <code>actual</code> to assert that the two different objects produce the same output. </p> <p> All test cases pass. </p> <h3 id="c2228ba4c0044dc8b90ad92354850a22"> Composition law <a href="#c2228ba4c0044dc8b90ad92354850a22" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>ContraMap</code> obeys the composition law for contravariant functors: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;&nbsp;7:45&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;18:13&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;18:13&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;18:13&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;22&quot;</span>&nbsp;&nbsp;&nbsp;,&nbsp;<span style="color:#a31515;">&quot;22&quot;</span>&nbsp;&nbsp;&nbsp;)] [InlineData(<span style="color:#a31515;">&quot;22:32&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;22&quot;</span>&nbsp;&nbsp;&nbsp;)] [InlineData(&nbsp;<span style="color:#a31515;">&quot;9&quot;</span>&nbsp;&nbsp;&nbsp;,&nbsp;&nbsp;<span style="color:#a31515;">&quot;9&quot;</span>&nbsp;&nbsp;&nbsp;)] [InlineData(&nbsp;<span style="color:#a31515;">&quot;9&quot;</span>&nbsp;&nbsp;&nbsp;,&nbsp;&nbsp;<span style="color:#a31515;">&quot;8&quot;</span>&nbsp;&nbsp;&nbsp;)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">CompositionLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">time1</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">time2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IEqualityComparer&lt;TimeDto&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDtoComparer(); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;(<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>)&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;(s,&nbsp;s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;(<span style="color:blue;">string</span>&nbsp;s,&nbsp;<span style="color:blue;">int</span>&nbsp;i),&nbsp;TimeDto&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDto&nbsp;{&nbsp;Time&nbsp;=&nbsp;t.s,&nbsp;MaximumPartySize&nbsp;=&nbsp;t.i&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;IEqualityComparer&lt;<span style="color:blue;">string</span>&gt;?&nbsp;<span style="color:#1f377f;">projection1</span>&nbsp;=&nbsp;sut.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;g(f(s))); &nbsp;&nbsp;&nbsp;&nbsp;IEqualityComparer&lt;<span style="color:blue;">string</span>&gt;?&nbsp;<span style="color:#1f377f;">projection2</span>&nbsp;=&nbsp;sut.ContraMap(g).ContraMap(f); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection1.Equals(time1,&nbsp;time2), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection2.Equals(time1,&nbsp;time2)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection1.GetHashCode(time1), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection2.GetHashCode(time1)); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Once more, you can't directly compare methods for equality, so instead you have to call both <code>Equals</code> and <code>GetHashCode</code> on <code>projection1</code> and <code>projection2</code> to verify that they return the same values. </p> <p> They do. </p> <h3 id="857e86fbf0944fe4b985cae73a9edb4b"> Relaxed assertion <a href="#857e86fbf0944fe4b985cae73a9edb4b" title="permalink">#</a> </h3> <p> The code base already contains a function that converts <code>Reservation</code> values to <code>ReservationDto</code> objects: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ReservationDto&nbsp;<span style="color:#74531f;">ToDto</span>(<span style="color:blue;">this</span>&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(reservation&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(reservation)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationDto &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;reservation.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;At&nbsp;=&nbsp;reservation.At.ToIso8601DateTimeString(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;reservation.Email.ToString(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;=&nbsp;reservation.Name.ToString(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;reservation.Quantity &nbsp;&nbsp;&nbsp;&nbsp;}; }</pre> </p> <p> Given that it's possible to map from <code>Reservation</code> to <code>ReservationDto</code>, it's also possible to map equality comparers in the contrary direction: from <code>IEqualityComparer&lt;ReservationDto&gt;</code> to <code>IEqualityComparer&lt;Reservation&gt;</code>. That's just what the <code>PostValidReservationWhenDatabaseIsEmpty</code> test needs! </p> <p> Most of the test stays the same, but you can now write the assertion as: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;Guid.NewGuid(), &nbsp;&nbsp;&nbsp;&nbsp;at, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Email(email), &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Name(name&nbsp;??&nbsp;<span style="color:#a31515;">&quot;&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;quantity); Assert.Contains( &nbsp;&nbsp;&nbsp;&nbsp;expected, &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationDtoComparer().ContraMap((Reservation&nbsp;<span style="color:#1f377f;">r</span>)&nbsp;=&gt;&nbsp;r.ToDto()));</pre> </p> <p> Instead of using the too-strict equality comparison of <code>Reservation</code>, the assertion now takes advantage of the relaxed, test-specific comparison of <code>ReservationDto</code> objects. </p> <p> What's not to like? </p> <p> To be truthful, this probably isn't a trick I'll perform often. I think it's fair to consider contravariant functors an advanced programming concept. On a team, I'd be concerned that colleagues wouldn't understand what's going on here. </p> <p> The purpose of this article series isn't to advocate for this style of programming. It's to show some realistic examples of contravariant functors. </p> <p> Even in <a href="https://www.haskell.org">Haskell</a>, where contravariant functors are en explicit part of <a href="https://hackage.haskell.org/package/base/docs/index.html">the <em>base</em> package</a>, I can't recall having availed myself of this functionality. </p> <h3 id="50a1d26e56054e8f896af110d176e3a5"> Equivalence in Haskell <a href="#50a1d26e56054e8f896af110d176e3a5" title="permalink">#</a> </h3> <p> The <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">Haskell <em>Data.Functor.Contravariant</em> module</a> defines a <code>Contravariant</code> type class and some instances to go with it. One of these is a <code>newtype</code> called <code>Equivalence</code>, which is just a wrapper around <code>a -&gt; a -&gt; Bool</code>. </p> <p> In Haskell, equality is normally defined by the <code>Eq</code> type class. You can trivially 'promote' any <code>Eq</code> instance to an <code>Equivalence</code> instance using the <code>defaultEquivalence</code> value. </p> <p> To illustrate how this works in Haskell, you can reproduce the two reservation types: </p> <p> <pre><span style="color:blue;">data</span>&nbsp;Reservation&nbsp;=&nbsp;Reservation&nbsp;{ &nbsp;&nbsp;<span style="color:#2b91af;">reservationID</span>&nbsp;::&nbsp;<span style="color:blue;">UUID</span>, &nbsp;&nbsp;<span style="color:#2b91af;">reservationAt</span>&nbsp;::&nbsp;<span style="color:blue;">LocalTime</span>, &nbsp;&nbsp;<span style="color:#2b91af;">reservationEmail</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">reservationName</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">reservationQuantity</span>&nbsp;::&nbsp;<span style="color:#2b91af;">Int</span>&nbsp;} &nbsp;&nbsp;<span style="color:blue;">deriving</span>&nbsp;(<span style="color:#2b91af;">Eq</span>,&nbsp;<span style="color:#2b91af;">Show</span>) <span style="color:blue;">data</span>&nbsp;ReservationJson&nbsp;=&nbsp;ReservationJson&nbsp;{ &nbsp;&nbsp;<span style="color:#2b91af;">jsonAt</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">jsonEmail</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">jsonName</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">jsonQuantity</span>&nbsp;::&nbsp;<span style="color:#2b91af;">Double</span>&nbsp;} &nbsp;&nbsp;<span style="color:blue;">deriving</span>&nbsp;(<span style="color:#2b91af;">Eq</span>,&nbsp;<span style="color:#2b91af;">Show</span>,&nbsp;<span style="color:#2b91af;">Read</span>,&nbsp;<span style="color:#2b91af;">Generic</span>)</pre> </p> <p> The <code>ReservationJson</code> type doesn't have an ID, whereas <code>Reservation</code> does. Still, you can easily convert from <code>Reservation</code> to <code>ReservationJson</code>: </p> <p> <pre><span style="color:#2b91af;">reservationToJson</span>&nbsp;::&nbsp;<span style="color:blue;">Reservation</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">ReservationJson</span> reservationToJson&nbsp;(Reservation&nbsp;_&nbsp;at&nbsp;email&nbsp;name&nbsp;q)&nbsp;= &nbsp;&nbsp;ReservationJson&nbsp;(<span style="color:blue;">show</span>&nbsp;at)&nbsp;email&nbsp;name&nbsp;(<span style="color:blue;">fromIntegral</span>&nbsp;q)</pre> </p> <p> Now imagine that you have two reservations that differ only on <code>reservationID</code>: </p> <p> <pre><span style="color:#2b91af;">reservation1</span>&nbsp;::&nbsp;<span style="color:blue;">Reservation</span> reservation1&nbsp;= &nbsp;&nbsp;Reservation &nbsp;&nbsp;&nbsp;&nbsp;(fromWords&nbsp;3822151499&nbsp;288494060&nbsp;2147588346&nbsp;2611157519) &nbsp;&nbsp;&nbsp;&nbsp;(LocalTime&nbsp;(fromGregorian&nbsp;2021&nbsp;11&nbsp;11)&nbsp;(TimeOfDay&nbsp;12&nbsp;30&nbsp;0)) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;just.inhale@example.net&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;Justin&nbsp;Hale&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;2 <span style="color:#2b91af;">reservation2</span>&nbsp;::&nbsp;<span style="color:blue;">Reservation</span> reservation2&nbsp;= &nbsp;&nbsp;Reservation &nbsp;&nbsp;&nbsp;&nbsp;(fromWords&nbsp;1263859666&nbsp;288625132&nbsp;2147588346&nbsp;2611157519) &nbsp;&nbsp;&nbsp;&nbsp;(LocalTime&nbsp;(fromGregorian&nbsp;2021&nbsp;11&nbsp;11)&nbsp;(TimeOfDay&nbsp;12&nbsp;30&nbsp;0)) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;just.inhale@example.net&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;Justin&nbsp;Hale&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;2</pre> </p> <p> If you compare these two values using the standard equality operator, they're (not surprisingly) not the same: </p> <p> <pre>&gt; reservation1 == reservation2 False</pre> </p> <p> Attempting to compare them using the default <code>Equivalence</code> value doesn't help, either: </p> <p> <pre>&gt; (getEquivalence $ defaultEquivalence) reservation1 reservation2 False</pre> </p> <p> But if you promote the comparison to <code>Equivalence</code> and then <code>contramap</code> it with <code>reservationToJson</code>, they do look the same: </p> <p> <pre>&gt; (getEquivalence $ contramap reservationToJson $ defaultEquivalence) reservation1 reservation2 True</pre> </p> <p> This Haskell example is equivalent in spirit to the above C# assertion. </p> <p> Notice that <code>Equivalence</code> is only a wrapper around any function of the type <code>a -&gt; a -&gt; Bool</code>. This corresponds to the <code>IEqualityComparer</code> interface's <code>Equals</code> method. On the other hand, <code>Equivalence</code> has no counterpart to <code>GetHashCode</code> - that's a .NETism. </p> <p> When using Haskell as inspiration for identifying universal abstractions, it's not entirely clear how <code>Equivalence</code> is similar to <code>IEqualityComparer&lt;T&gt;</code>. While <code>a -&gt; a -&gt; Bool</code> is isomorphic to its <code>Equals</code> method, and thus gives rise to a contravariant functor, what about the <code>GetHashCode</code> method? </p> <p> As this article has demonstrated, it turned out that it's possible to also contramap the <code>GetHashCode</code> method, but was that just a fortunate accident, or is there something more fundamental going on? </p> <h3 id="d51dbd1743e14420ab8c38b25bc02369"> Conclusion <a href="#d51dbd1743e14420ab8c38b25bc02369" title="permalink">#</a> </h3> <p> Equivalence relations give rise to a contravariant functor. In this article, you saw how this property can be used to relax assertions in unit tests. </p> <p> Strictly speaking, an equivalence relation is exclusively a function that compares two values to return a Boolean value. No <code>GetHashCode</code> method is required. That's a .NET-specific implementation detail that, unfortunately, has been allowed to leak into the <code>object</code> base class. It's not part of the concept of an equivalence relation, but still, it's possible to form a contravariant functor from <code>IEqualityComparer&lt;T&gt;</code>. Is this just a happy coincidence, or could there be something more fundamental going on? </p> <p> Read on. </p> <p> <strong>Next:</strong> <a href="/2021/10/04/reader-as-a-contravariant-functor">Reader as a contravariant functor</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Keep IDs internal with REST https://blog.ploeh.dk/2021/09/20/keep-ids-internal-with-rest 2021-09-20T06:21:00+00:00 Mark Seemann <div id="post"> <p> <em>Instead of relying on entity IDs, use hypermedia to identify resources.</em> </p> <p> Whenever I've helped teams design HTTP APIs, sooner or later one request comes up - typically from client developers: <em>Please add the entity ID to the representation.</em> </p> <p> In this article I'll show an alternative, but first: the normal state of affairs. </p> <h3 id="24703d08faec4fe6a650599e54e8dbf8"> Business as usual <a href="#24703d08faec4fe6a650599e54e8dbf8" title="permalink">#</a> </h3> <p> It's such a common requirement that, despite admonitions not to expose IDs, I did it myself in the code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. This code base is a <a href="https://martinfowler.com/articles/richardsonMaturityModel.html">level 3 REST API</a>, and still, I'd included the ID in the JSON representation of a reservation: </p> <p> <pre>{ &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;bf4e84130dac451b9c94049da8ea8c17&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 }</pre> </p> <p> At least the ID is a <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">GUID</a>, so I'm <a href="/2014/08/11/cqs-versus-server-generated-ids">not exposing internal database IDs</a>. </p> <p> After having written the book, the <code>id</code> property kept nagging me, and I wondered if it'd be possible to get rid of it. After all, in a true REST API, clients aren't supposed to construct URLs from templates. They're supposed to follow links. So why do you need the ID? </p> <h3 id="e480deb4e2b3470a847fc2995bdf406d"> Following links <a href="#e480deb4e2b3470a847fc2995bdf406d" title="permalink">#</a> </h3> <p> Early on in the system's lifetime, I began <a href="/2020/10/26/fit-urls">signing all URLs</a> to prevent clients from <a href="/2013/05/01/rest-lesson-learned-avoid-hackable-urls">retro-engineering URLs</a>. This also meant that most of my <a href="/2021/01/25/self-hosted-integration-tests-in-aspnet">self-hosted integration tests</a> were already following links: </p> <p> <pre>[Theory] [InlineData(867,&nbsp;19,&nbsp;10,&nbsp;<span style="color:#a31515;">&quot;adur@example.net&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Adrienne&nbsp;Ursa&quot;</span>,&nbsp;2)] [InlineData(901,&nbsp;18,&nbsp;55,&nbsp;<span style="color:#a31515;">&quot;emol@example.gov&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Emma&nbsp;Olsen&quot;</span>,&nbsp;5)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">ReadSuccessfulReservation</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">days</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">hours</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">minutes</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">email</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">name</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantity</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">using</span>&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">api</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;LegacyApi(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">at</span>&nbsp;=&nbsp;DateTime.Today.AddDays(days).At(hours,&nbsp;minutes) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ToIso8601DateTimeString(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;Create.ReservationDto(at,&nbsp;email,&nbsp;name,&nbsp;quantity); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">postResp</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;api.PostReservation(expected); &nbsp;&nbsp;&nbsp;&nbsp;Uri&nbsp;<span style="color:#1f377f;">address</span>&nbsp;=&nbsp;FindReservationAddress(postResp); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">getResp</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;api.CreateClient().GetAsync(address); &nbsp;&nbsp;&nbsp;&nbsp;getResp.EnsureSuccessStatusCode(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;getResp.ParseJsonContent&lt;ReservationDto&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;actual,&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationDtoComparer()); &nbsp;&nbsp;&nbsp;&nbsp;AssertUrlFormatIsIdiomatic(address); }</pre> </p> <p> This parametrised test uses <a href="https://xunit.net">xUnit.net</a> 2.4.1 to first post a new reservation to the system, and then following the link provided in the response's <code>Location</code> header to verify that this resource contains a representation compatible with the reservation that was posted. </p> <p> A corresponding plaintext HTTP session would start like this: </p> <p> <pre>POST /restaurants/90125/reservations?sig=aco7VV%2Bh5sA3RBtrN8zI8Y9kLKGC60Gm3SioZGosXVE%3D HTTP/1.1 Content-Type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08&nbsp;20:30&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 } HTTP/1.1 201 Created Content-Type: application/json; charset=utf-8 Location: example.com/restaurants/90125/reservations/bf4e84130dac451b9c94049da8ea8c17?sig=ZVM%2[...] { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;bf4e84130dac451b9c94049da8ea8c17&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 }</pre> </p> <p> That's the first request and response. Clients can now examine the response's headers to find the <code>Location</code> header. That URL is the actual, external ID of the resource, not the <code>id</code> property in the JSON representation. </p> <p> The client can save that URL and request it whenever it needs the reservation: </p> <p> <pre>GET /restaurants/90125/reservations/bf4e84130dac451b9c94049da8ea8c17?sig=ZVM%2[...] HTTP/1.1 HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;bf4e84130dac451b9c94049da8ea8c17&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 }</pre> </p> <p> The actual, intended use of the API doesn't rely on the <code>id</code> property, neither do the tests. </p> <p> Based on this consistent design principle, I had reason to hope that I'd be able to remove the <code>id</code> property. </p> <h3 id="f4fc880aa8434cc2ac1675fcdf68bc18"> Breaking change <a href="#f4fc880aa8434cc2ac1675fcdf68bc18" title="permalink">#</a> </h3> <p> My motivation for making this change was to educate myself. I wanted to see if it would be possible to design a REST API that doesn't expose IDs in their JSON (or XML) representations. Usually I'm having trouble doing this in practice because when I'm consulting, I'm typically present to help the organisation with test-driven development and how to organise their code. It's always hard to learn new ways of doing things, and I don't wish to overwhelm my clients with too many changes all at once. </p> <p> So I usually let them do <a href="https://martinfowler.com/articles/richardsonMaturityModel.html">level 2 APIs</a> because that's what they're comfortable with. With that style of HTTP API design, it's hard to avoid <code>id</code> fields. </p> <p> This wasn't a constraint for the book's code, so I'd gone full REST on that API, and I'm happy that I did. By habit, though, I'd exposed the <code>id</code> property in JSON, and I now wanted to perform an experiment: Could I remove the field? </p> <p> A word of warning: You can't just remove a JSON property from a production API. That would constitute a breaking change, and even though clients aren't supposed to use the <code>id</code>, <a href="https://www.hyrumslaw.com">Hyrum's law</a> says that someone somewhere probably already is. </p> <p> This is just an experiment that I carried out on a separate Git branch, for my own edification. </p> <h3 id="3cf78b876e2a4f91b3e49b91f89bde02"> Leaning on the compiler <a href="#3cf78b876e2a4f91b3e49b91f89bde02" title="permalink">#</a> </h3> <p> As outlined, I had relatively strong faith in my test suite, so I decided to modify the <a href="https://en.wikipedia.org/wiki/Data_transfer_object">Data Transfer Object</a> (DTO) in question. Before the change, it looked like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ReservationDto</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;LinkDto[]?&nbsp;Links&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;Id&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;At&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;Email&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;Name&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">int</span>&nbsp;Quantity&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} }</pre> </p> <p> At first, I simply tried to delete the <code>Id</code> property, but while it turned out to be not too bad in general, it did break one feature: The ability of <a href="/2020/08/24/adding-rest-links-as-a-cross-cutting-concern">the LinksFilter</a> to generate links to reservations. Instead, I changed the <code>Id</code> property to be internal: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ReservationDto</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;LinkDto[]?&nbsp;Links&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;Id&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;At&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;Email&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;Name&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">int</span>&nbsp;Quantity&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} }</pre> </p> <p> This enables the <code>LinksFilter</code> and other internal code to still access the <code>Id</code> property, while the unit tests no longer could. As expected, this change caused some compiler errors. That was expected, and my plan was to <em>lean on the compiler</em>, as <a href="https://michaelfeathers.silvrback.com">Michael Feathers</a> describes in <a href="http://bit.ly/working-effectively-with-legacy-code">Working Effectively with Legacy Code</a>. </p> <p> As I had hoped, relatively few things broke, and they were fixed in 5-10 minutes. Once everything compiled, I ran the tests. Only a single test failed, and this was a unit test that used some Back Door Manipulation, as <a href="http://bit.ly/xunitpatterns">xUnit Test Patterns</a> terms it. I'll return to that test in <a href="/2021/09/27/the-equivalence-contravariant-functor">a future article</a>. </p> <p> None of my self-hosted integration tests failed. </p> <h3 id="d65ef3b7816c4f73b1060af4532fe1dc"> ID-free interaction <a href="#d65ef3b7816c4f73b1060af4532fe1dc" title="permalink">#</a> </h3> <p> Since clients are supposed to follow links, they can still do so. For example, a <a href="https://en.wikipedia.org/wiki/Maître_d%27hôtel">maître d'hôtel</a> might request the day's schedule: </p> <p> <pre>GET /restaurants/90125/schedule/2021/12/8?sig=82fosBYsE9zSKkA4Biy5t%2BFMxl71XiLlFKaI2E[...] HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZXN0YXVyYW50IjpbIjEiLCIyMTEyIiwi[...] HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;The&nbsp;Vatican&nbsp;Cellar&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;year&quot;</span>:&nbsp;2021, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;month&quot;</span>:&nbsp;12, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;day&quot;</span>:&nbsp;8, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;days&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;date&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;entries&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;time&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;20:30:00&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;reservations&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;links&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;rel&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;urn:reservation&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;href&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;http://example.com/restaurants/90125/reservations/bf4e84130dac4[...]&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;] }</pre> </p> <p> I've edited the response quite heavily by removing other links, and so on. </p> <p> Clients that wish to navigate to Snow Moe Beal's reservation must locate its <code>urn:reservation</code> link and use the corresponding <code>href</code> value. This is an opaque URL that clients can use to make requests: </p> <p> <pre>GET /restaurants/90125/reservations/bf4e84130dac451b9c94049da8ea8c17?sig=vxkBT1g1GHRmx[...] HTTP/1.1 HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 }</pre> </p> <p> In none of these interactions do clients rely on the <code>id</code> property - which is also gone now. It's gone because the <code>Id</code> property on the C# DTO is <code>internal</code>, which means that it's not being rendered. </p> <p> Mission accomplished. </p> <h3 id="849eb1540d7145c78415976e8c662597"> Conclusion <a href="#849eb1540d7145c78415976e8c662597" title="permalink">#</a> </h3> <p> It always grates on me when I have to add an <code>id</code> property to a representation in an HTTP API. It's often necessary when working with a level 2 API, but with a proper hypermedia-driven REST API, it may not be necessary. </p> <p> At least, the experiment I performed with the code base from my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> indicates that this may be so. </p> </div> <div id="comments"> <hr> <h2 id="comments-header">Comments</h2> <div class="comment" id="cd972bab11b74bf382c5796f5b0bec7a"> <div class="comment-author"><a href="https://www.relativisticramblings.com/">Christer van der Meeren</a></div> <div class="comment-content"> <p>It seems to me that this approach will cause problems if 3rd parties need to integrate with your API in a way where they themselves need to store references to entities in your system. For example, they may expose your entities to their users with additional data in their systems/integrations. Sure, it is <em>possible</em> for them to use the URI as a primary key (<em>if</em> you guarantee a sensible max URI length; another can of worms), but if you internally use INT or UNIQUEIDENTIFIER as your primary key, I would not want to force them to use VARCHAR(whatever) as primary key.</p> <p>Therefore, in all our APIs, we document in the API specification that the IDs, though required by <a target="_blank" href="https://jsonapi.org/">JSON:API</a> (which we follow) to be passed as string values for consistency, can be safely assumed to be integers (or GUIDs, if relevant). We even document that they are <em>32-bit</em> ints, so any clients know they can safely use INT fields instead of BIGINT.</p> <p>JSON:API requires all entities to have a single ID. For obvious reasons, IDs should be stable. Therefore, for entities that represent an association between two other entities and do not have a separate, persisted ID, we have a need to have API IDs that contain information about the associated entities. To combat Hyrum's law, we typically concatenate the associated IDs using a known delimiter and encode the resulting string using a non-standard, URL-friendly encoding (i.e., not Base64, which may contain non-URL-friendly characters and is often obvious). This way, the IDs appear opaque to API clients. Of course, the format of these IDs are not documented in our API specifications, as they are not intended to be stored. Instead, the actual association is documented and the related entities retrievable (of course, since this information inherent to the entity's very nature), and the associated IDs may be used by clients in a multi-column primary key, just like we do.</p> <p>All of the above assumes that the integrating clients use a SQL database or similar. Let's face it; many do. If you have (or may hve in the future) a single client that do this, you have to take the above into account.</p> </div> <div class="comment-date">2021-09-20 9:07 UTC</div> </div> <div class="comment" id="2fa9b78a83b64b33ae16182ed7db450c"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Christer, thank you for writing. I think that one of the problems with discussions about REST APIs, or just HTTP APIs in general, is that people use them for all sorts of things. At one extreme, you have <a href="https://samnewman.io/patterns/architectural/bff/">Backends For Frontends</a>, where, if you aren't writing the API with the single client in mind, you're doing something wrong. At the other extreme, you have APIs that may have uncountable and unknown clients. When I write about REST, I mostly have the latter kind in mind. </p> <p> When designing APIs for many unknown clients, it makes little sense to take 'special needs' into account. Different clients may present mutually exclusive requirements. </p> <p> Clients that need to 'bookmark' REST resources in a database can do that by defining two columns: one an ordinary primary key column on which the table defines its clustered index, and another column for the link value itself, with a <code>UNIQUE</code> constraint. Something like this (in T-SQL dialect): </p> <p> <pre><span style="color:blue;">CREATE</span>&nbsp;<span style="color:blue;">TABLE</span>&nbsp;[dbo]<span style="color:gray;">.</span>[Foo]<span style="color:blue;">&nbsp;</span><span style="color:gray;">(</span> &nbsp;&nbsp;&nbsp;&nbsp;[Id]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">INT</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL</span>&nbsp;<span style="color:blue;">IDENTITY</span>&nbsp;<span style="color:blue;">PRIMARY</span>&nbsp;<span style="color:blue;">KEY</span>&nbsp;<span style="color:blue;">CLUSTERED</span><span style="color:gray;">,</span> &nbsp;&nbsp;&nbsp;&nbsp;[Address]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">NVARCHAR&nbsp;</span><span style="color:gray;">(</span>850<span style="color:gray;">)</span>&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL</span>&nbsp;<span style="color:blue;">UNIQUE</span>&nbsp;<span style="color:blue;">NONCLUSTERED</span><span style="color:gray;">,</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">--&nbsp;Other&nbsp;columns&nbsp;go&nbsp;here...</span> <span style="color:gray;">);</span></pre> </p> <p> Client code can look up an API resource on internal key, or on address, as required. </p> </div> <div class="comment-date">2021-09-21 16:27 UTC</div> </div> <div class="comment" id="6a7b06cf97e9453bafe5ddafa5156093"> <div class="comment-author"><a href="https://www.relativisticramblings.com/">Christer van der Meeren</a></div> <div class="comment-content"> <p>Your URLs include a signature, which changes if you need to switch signing keys. Furthermore, the base URL for your API may change. The entities are still the same; the restaurant previously at old.domain/restaurants/1?sig=abc is the same as the restaurant now at new.domain/restaurants/1?sig=123. With your proposed bookmark-based solution, the API clients would effectively lose the associations in their system.</p> <p>Also, indexing a very long varchar column probably works fine for tables that are fairly small and not overly busy. But for large and/or busy tables containing entities that are created every second of every day (say, passages through gates at hundreds of large construction sites, which is one of the domains I work with), I think that the performance would suffer unreasonably. (Admittedly, I have of course not measured this; this is just speculation, and anyway not my main point.)</p> <p>You say you write APIs with arbitrary clients in mind. I do, too. That is one of the reasons I design my APIs at REST level 2 instead of 3. (JSON:API does offer some possibility of just "following links" if the client wishes to do that, though it is does not allow for APIs that are fully level 3/HATEOAS.) Having stable IDs with well-known formats and being able to construct URLs seems pragmatically like a good solution that keeps client developers happy. I do not have decades of experience, but I have never encountered clients who have been unhappy with my decision to go for level 2 instead of level 3. (I imagine I would have encountered some resistance in the opposite case, though that is pure speculation on my part.) Furthermore, I have never encountered the need for breaking changes that would be non-breaking by level 3 standards.</p> <p>You say it makes little sense to take "special needs" into account. Idealistically, I agree. Pragmatically, 1) SQL databases are so ubiquitous and have been for such a long time that making life better for those developers by including an ID with a guaranteed format seems like a fair decision, and 2) our APIs (and many others, I assume) are created not just for 3rd party integration but also for one or more 1st party front-ends, which naturally tends to receive some preferential treatment (e.g. features and designs that probably aren't useful to other clients).</p> </div> <div class="comment-date">2021-09-21 20:56 UTC</div> </div> <div class="comment" id="e1a154854b014ab8ad218b076579db4c"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Christer, thank you for writing. It's possible that I'm going about this the wrong way. I only report on what's been working for me, but that said, while I <em>do</em> have decades of general programming experience, I don't have decades of REST experience. I designed my first REST API in 2012. </p> <p> Additionally, just because one style of API design works well, that doesn't rule out that other types of design also work. </p> <p> Finally, this particular article is an experiment. I've never done something like this in the wild, so it's possible that it does have unforeseen issues. </p> <p> A couple of answers to your various points, though: </p> <p> I don't foresee having to change signing keys, but if that happens, it'd be a breaking change to remove support for old keys. One might have to, instead, retire old signing keys in the same way one can <a href="/2020/06/01/retiring-old-service-versions">retire old service versions</a>. Even if a key gets 'compromised', it's not an immediate issue. It only means that any client that possesses the leaked key <em>can</em> construct URLs directly by <a href="/2013/05/01/rest-lesson-learned-avoid-hackable-urls">retro-engineering implied URL templates</a>. This would still be undocumented and unsupported use of the API, which means that ultimately, it'd be against the client developers' own self-interest in doing that. </p> <p> <a href="/2020/10/26/fit-urls">Signing the URLs isn't a security measure</a>; it's more like a <a href="https://en.wikipedia.org/wiki/Nudge_theory">nudge</a>. </p> <blockquote> <p> "our APIs (and many others, I assume) are created not just for 3rd party integration but also for one or more 1st party front-ends, which naturally tends to receive some preferential treatment" </p> </blockquote> <p> I've written APIs like that as well, and if there's one thing I've learned from doing that is that if I'm ever again put in charge of such an API, I'll strongly resist giving preferential treatment to any clients. If a particular client needs a particular feature, the client team can develop and maintain a Backend for Frontend, which bases its own implementation on the general-purpose API. </p> <p> My experience with supporting particular clients is that client needs evolve much faster than APIs. This makes sense. Someone wants to do <a href="https://en.wikipedia.org/wiki/A/B_testing">A/B testing</a> on the client's user interface. Depending on the outcome of such a test, at least one of the supporting features will now be obsolete. I'm not much inclined having to support such features in an API where backwards compatibility is critical. </p> <p> But again, these things are never clear-cut. Much depends on the overall goals of the organisation - and these may also change over time. I'm not claiming that my way is <em>best</em> - only that it's possible. </p> </div> <div class="comment-date">2021-09-23 8:07 UTC</div> </div> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Unit testing private helper methods https://blog.ploeh.dk/2021/09/13/unit-testing-private-helper-methods 2021-09-13T05:25:00+00:00 Mark Seemann <div id="post"> <p> <em>Evolving a private helper method, guided by tests.</em> </p> <p> A frequently asked question about unit testing and test-driven development (TDD) is how to test private helper methods. I've <a href="/2015/09/22/unit-testing-internals">already attempted to answer that question: <em>through the public API</em></a>, but a recent comment to <a href="https://stackoverflow.com/a/69141655/126014">a Stack Overflow question</a> made me realise that I've failed to supply a code example. </p> <p> Show, don't tell. </p> <p> In this article I'll show a code example that outlines how a private helper method can evolve under TDD. </p> <h3 id="03e1e533e1514945812c557b006883c3"> Threshold <a href="#03e1e533e1514945812c557b006883c3" title="permalink">#</a> </h3> <p> The code example in this article comes from my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. When you buy the book, you get not only the finished code examples, but the entire Git repository, with detailed commit messages. </p> <p> A central part of the code base is a method that decides whether or not to accept a reservation attempt. It's essentially a solution to <a href="/2020/01/27/the-maitre-d-kata/">the Maître d' kata</a>. I wrote most of the book's code with TDD, and after commit <code>fa12fd69c158168178f3a75bcd900e5caa7e7dec</code> I decided that I ought to refactor the implementation. As I wrote in the commit message: </p> <p> <pre>Filter later reservations based on date The line count of the willAccept method has now risen to 28. Cyclomatic complexity is still at 7. It's ripe for refactoring.</pre> </p> <p> I think, by the way, that I made a small mistake. As far as I can tell, the <code>WillAccept</code> line count in this commit is <em>26</em> - not <em>28:</em> </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">WillAccept</span>( &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Reservation&gt;&nbsp;<span style="color:#1f377f;">existingReservations</span>, &nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;<span style="color:#1f377f;">candidate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(existingReservations&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(existingReservations)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(candidate&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(candidate)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">relevantReservations</span>&nbsp;=&nbsp;existingReservations &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Where(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;candidate.At.Date&nbsp;==&nbsp;r.At.Date); &nbsp;&nbsp;&nbsp;&nbsp;List&lt;Table&gt;&nbsp;<span style="color:#1f377f;">availableTables</span>&nbsp;=&nbsp;Tables.ToList(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">foreach</span>&nbsp;(var&nbsp;<span style="color:#1f377f;">r</span>&nbsp;<span style="color:#8f08c4;">in</span>&nbsp;relevantReservations) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">table</span>&nbsp;=&nbsp;availableTables.Find(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;r.Quantity&nbsp;&lt;=&nbsp;t.Seats); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(table&nbsp;<span style="color:blue;">is</span>&nbsp;{&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;availableTables.Remove(table); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(table.IsCommunal) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;availableTables.Add(table.Reserve(r.Quantity)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;availableTables.Any(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;candidate.Quantity&nbsp;&lt;=&nbsp;t.Seats); }</pre> </p> <p> Still, I knew that it wasn't done - that I'd be adding more tests that would increase both the size and complexity of the method. It was brushing against more than one <a href="/2020/04/13/curb-code-rot-with-thresholds">threshold</a>. I decided that it was time for a prophylactic refactoring. </p> <p> Notice that the <a href="/2019/10/21/a-red-green-refactor-checklist">red-green-refactor checklist</a> explicitly states that refactoring is part of the process. It doesn't, however, mandate that refactoring must be done in the same commit as the green phase. Here, I did <em>red-green-commit-refactor-commit</em>. </p> <p> While I decided to refactor, I also knew that I still had some way to go before <code>WillAccept</code> would be complete. With the code still in flux, I didn't want to couple tests to a new method, so I chose to extract a <code>private</code> helper method. </p> <h3 id="8db39405ecce4ee9b647866eed0e1383"> Helper method <a href="#8db39405ecce4ee9b647866eed0e1383" title="permalink">#</a> </h3> <p> After the refactoring, the code looked like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">WillAccept</span>( &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Reservation&gt;&nbsp;<span style="color:#1f377f;">existingReservations</span>, &nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;<span style="color:#1f377f;">candidate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(existingReservations&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(existingReservations)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(candidate&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(candidate)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">relevantReservations</span>&nbsp;=&nbsp;existingReservations &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Where(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;candidate.At.Date&nbsp;==&nbsp;r.At.Date); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">availableTables</span>&nbsp;=&nbsp;Allocate(relevantReservations); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;availableTables.Any(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;candidate.Quantity&nbsp;&lt;=&nbsp;t.Seats); } <span style="color:blue;">private</span>&nbsp;IEnumerable&lt;Table&gt;&nbsp;<span style="color:#74531f;">Allocate</span>( &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Reservation&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;List&lt;Table&gt;&nbsp;<span style="color:#1f377f;">availableTables</span>&nbsp;=&nbsp;Tables.ToList(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">foreach</span>&nbsp;(var&nbsp;<span style="color:#1f377f;">r</span>&nbsp;<span style="color:#8f08c4;">in</span>&nbsp;reservations) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">table</span>&nbsp;=&nbsp;availableTables.Find(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;r.Quantity&nbsp;&lt;=&nbsp;t.Seats); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(table&nbsp;<span style="color:blue;">is</span>&nbsp;{&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;availableTables.Remove(table); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(table.IsCommunal) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;availableTables.Add(table.Reserve(r.Quantity)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;availableTables; }</pre> </p> <p> I committed the change, and wrote in the commit message: </p> <p> <pre>Extract helper method from WillAccept This quite improves the complexity of the method, which is now 4, and at 18 lines of code. The new helper method also has a cyclomatic complexity of 4, and 17 lines of code. A remaining issue with the WillAccept method is that the code operates on different levels of abstraction. The call to Allocate represents an abstraction, while the filter on date is as low-level as it can get.</pre> </p> <p> As you can tell, I was well aware that there were remaining issues with the code. </p> <p> Since the new <code>Allocate</code> helper method is <code>private</code>, unit tests can't reach it directly. It's still <em>covered</em> by tests, though, just as that code block was before I extracted it. </p> <h3 id="b8928ae201444a78b7ca1715e486fb92"> More tests <a href="#b8928ae201444a78b7ca1715e486fb92" title="permalink">#</a> </h3> <p> I wasn't done with the <code>WillAccept</code> method, and after a bout of other refactorings, I added more test cases covering it. </p> <p> While the method ultimately grew to exhibit moderately complex behaviour, I had only two test methods covering it: one (not shown) for the rejection case, and another for the accept (<code>true</code>) case: </p> <p> <pre>[Theory,&nbsp;ClassData(<span style="color:blue;">typeof</span>(AcceptTestCases))] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Accept</span>( &nbsp;&nbsp;&nbsp;&nbsp;TimeSpan&nbsp;<span style="color:#1f377f;">seatingDuration</span>, &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Table&gt;&nbsp;<span style="color:#1f377f;">tables</span>, &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Reservation&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;MaitreD(seatingDuration,&nbsp;tables); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;Some.Reservation.WithQuantity(11); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.WillAccept(reservations,&nbsp;r); &nbsp;&nbsp;&nbsp;&nbsp;Assert.True(actual); }</pre> </p> <p> I based the example code on the <a href="/2020/03/02/impureim-sandwich">impureim sandwich architecture</a>, which meant that domain logic (including the <code>WillAccept</code> method) is all <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. The nice thing about pure functions is that <a href="/2015/05/07/functional-design-is-intrinsically-testable">they're easy to unit test</a>. </p> <p> The <code>Accept</code> test method uses an object data source (see the article <a href="/2021/01/18/parametrised-test-primitive-obsession-code-smell">Parametrised test primitive obsession code smell</a> for another example of the motivation behind using objects for test parametrisation), so adding more test cases were simply a matter of adding them to the data source: </p> <p> <pre><span style="color:silver;">Add(TimeSpan.FromHours(6), &nbsp;&nbsp;&nbsp;&nbsp;new[]&nbsp;{&nbsp;Table.Communal(11)&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;new[]&nbsp;{&nbsp;Some.Reservation.WithQuantity(11).TheDayAfter()&nbsp;});</span> Add(TimeSpan.FromHours(2.5), &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;Table.Standard(12)&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;Some.Reservation.WithQuantity(11).AddDate( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TimeSpan.FromHours(-2.5))&nbsp;}); Add(TimeSpan.FromHours(1), &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;Table.Standard(14)&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;Some.Reservation.WithQuantity(9).AddDate( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TimeSpan.FromHours(1))&nbsp;});</pre> </p> <p> The bottom two test cases are new additions. In that way, by adding new test cases, I could keep evolving <code>WillAccept</code> and its various private helper methods (of which I added more). While no tests directly exercise the private helper methods, the unit tests still <a href="https://en.wikipedia.org/wiki/Transitive_relation">transitively</a> exercise the private parts of the code base. </p> <p> Since I followed TDD, no private helper methods sprang into existence untested. I didn't have to jump through hoops in order to be able to unit test private helper methods. Rather, the private helper methods were a natural by-product of the red-green-refactor process - particularly, the <em>refactor</em> phase. </p> <h3 id="6c5f4e12a3cb4318a3331cf4f2485028"> Conclusion <a href="#6c5f4e12a3cb4318a3331cf4f2485028" title="permalink">#</a> </h3> <p> Following TDD doesn't preclude the creation of private helper methods. In fact, private helper methods can (and should?) emerge during the refactoring phase of the red-green-refactoring cycle. </p> <p> For long-time practitioners of TDD, there's nothing new in this, but people new to TDD are still learning. This question keeps coming up, so I hope that this example is useful. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. The Specification contravariant functor https://blog.ploeh.dk/2021/09/09/the-specification-contravariant-functor 2021-09-09T09:12:00+00:00 Mark Seemann <div id="post"> <p> <em>An introduction for object-oriented programmers to the Specification contravariant functor.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction. In the <a href="/2021/09/06/the-command-handler-contravariant-functor">previous article</a>, you saw an example of a contravariant functor based on the Command Handler pattern. This article gives another example. </p> <p> <a href="http://amzn.to/WBCwx7">Domain-Driven Design</a> discusses the benefits of the <a href="https://en.wikipedia.org/wiki/Specification_pattern">Specification pattern</a>. In its generic incarnation this pattern gives rise to a contravariant functor. </p> <h3 id="2d6538ee35d84c47808f6b162f61eeb3"> Interface <a href="#2d6538ee35d84c47808f6b162f61eeb3" title="permalink">#</a> </h3> <p> <a href="http://amzn.to/WBCwx7">DDD</a> introduces the pattern with a non-generic <code>InvoiceSpecification</code> interface. The book also shows other examples, and it quickly becomes clear that with generics, you can generalise the pattern to this interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">ISpecification</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(T&nbsp;<span style="color:#1f377f;">candidate</span>); }</pre> </p> <p> Given such an interface, you can implement standard reusable Boolean logic such as <em>and</em>, <em>or</em>, and <em>not</em>. (Exercise: consider how implementations of <em>and</em> and <em>or</em> correspond to well-known <a href="/2017/10/06/monoids">monoids</a>. Do the implementations look like <a href="https://en.wikipedia.org/wiki/Composite_pattern">Composites</a>? <a href="/2018/03/12/composite-as-a-monoid">Is that a coincidence?</a>) </p> <p> The <code>ISpecification&lt;T&gt;</code> interface is really just a glorified predicate. These days the Specification pattern may seem somewhat exotic in languages with first-class functions. C#, for example, defines both a <a href="https://docs.microsoft.com/dotnet/api/system.predicate-1">specialised Predicate delegate</a>, as well as the more general <code>Func&lt;T, bool&gt;</code> delegate. Since you can pass those around as objects, that's often good enough, and you don't need an <code>ISpecification</code> interface. </p> <p> Still, for the sake of argument, in this article I'll start with the Specification pattern and demonstrate how that gives rise to a contravariant functor. </p> <h3 id="a13ce5becb564762847a6876f87aa16f"> Natural number specification <a href="#a13ce5becb564762847a6876f87aa16f" title="permalink">#</a> </h3> <p> Consider the <code>AdjustInventoryService</code> class from <a href="/2021/09/06/the-command-handler-contravariant-functor">the previous article</a>. I'll repeat the 'original' <code>Execute</code> method here: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantityAdjustment</span>&nbsp;=&nbsp;command.Quantity&nbsp;*&nbsp;(command.Decrease&nbsp;?&nbsp;-1&nbsp;:&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.AdjustQuantity(quantityAdjustment); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(productInventory.Quantity&nbsp;&lt;&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;InvalidOperationException(<span style="color:#a31515;">&quot;Can&#39;t&nbsp;decrease&nbsp;below&nbsp;0.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory); }</pre> </p> <p> Notice the Guard Clause: </p> <p> <pre><span style="color:#8f08c4;">if</span>&nbsp;(productInventory.Quantity&nbsp;&lt;&nbsp;0)</pre> </p> <p> Image that we'd like to introduce some flexibility here. It's admittedly a silly example, but just come along for the edification. Imagine that we'd like to use an injected <code>ISpecification&lt;ProductInventory&gt;</code> instead: </p> <p> <pre><span style="color:#8f08c4;">if</span>&nbsp;(!specification.IsSatisfiedBy(productInventory))</pre> </p> <p> That doesn't sound too difficult, but what if you only have an <code>ISpecification</code> implementation like the following? </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">NaturalNumber</span>&nbsp;:&nbsp;ISpecification&lt;<span style="color:blue;">int</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ISpecification&lt;<span style="color:blue;">int</span>&gt;&nbsp;Specification&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;NaturalNumber(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">NaturalNumber</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">candidate</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;0&nbsp;&lt;=&nbsp;candidate; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> That's essentially what you need, but alas, it only implements <code>ISpecification&lt;int&gt;</code>, not <code>ISpecification&lt;ProductInventory&gt;</code>. Do you <em>really</em> have to write a new <a href="https://en.wikipedia.org/wiki/Adapter_pattern">Adapter</a> just to implement the right interface? </p> <p> No, you don't. </p> <h3 id="069f9ff7ee4d41dab4cf9243804dc873"> Contravariant functor <a href="#069f9ff7ee4d41dab4cf9243804dc873" title="permalink">#</a> </h3> <p> Fortunately, an interface like <code>ISpecification&lt;T&gt;</code> gives rise to a contravariant functor. This will enable you to compose an <code>ISpecification&lt;ProductInventory&gt;</code> object from the <code>NaturalNumber</code> specification. </p> <p> In order to enable contravariant mapping, you must add a <code>ContraMap</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ISpecification&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ContraSpecification&lt;T,&nbsp;T1&gt;(source,&nbsp;selector); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ContraSpecification</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;&nbsp;:&nbsp;ISpecification&lt;T1&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;ISpecification&lt;T&gt;&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ContraSpecification</span>(ISpecification&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.source&nbsp;=&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.selector&nbsp;=&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(T1&nbsp;<span style="color:#1f377f;">candidate</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.IsSatisfiedBy(selector(candidate)); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Notice that, as explained in the overview article, in order to map from an <code>ISpecification&lt;T&gt;</code> to an <code>ISpecification&lt;T1&gt;</code>, the <code>selector</code> has to go the other way: from <code>T1</code> to <code>T</code>. How this is possible will become more apparent with an example, which will follow later in the article. </p> <h3 id="f3211a80973c4d85b63a564704e67028"> Identity law <a href="#f3211a80973c4d85b63a564704e67028" title="permalink">#</a> </h3> <p> A <code>ContraMap</code> method with the right signature isn't enough to be a contravariant functor. It must also obey the contravariant functor laws. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the identity law for the <code>ISpecification&lt;T&gt;</code> interface. In this article, you'll see parametrised tests written with <a href="https://xunit.net">xUnit.net</a>. First, the identity law: </p> <p> <pre>[Theory] [InlineData(-102)] [InlineData(&nbsp;&nbsp;-3)] [InlineData(&nbsp;&nbsp;-1)] [InlineData(&nbsp;&nbsp;&nbsp;0)] [InlineData(&nbsp;&nbsp;&nbsp;1)] [InlineData(&nbsp;&nbsp;32)] [InlineData(&nbsp;283)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityLaw</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;ISpecification&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.ContraMap&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;(id); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.IsSatisfiedBy(input), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection.IsSatisfiedBy(input)); }</pre> </p> <p> In order to observe that the two Specifications have identical behaviours, the test has to invoke <code>IsSatisfiedBy</code> on both of them to verify that the return values are the same. </p> <p> All test cases pass. </p> <h3 id="84d4761adecd427fbd9e463a05e8cc67"> Composition law <a href="#84d4761adecd427fbd9e463a05e8cc67" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>ContraMap</code> obeys the composition law for contravariant functors: </p> <p> <pre>[Theory] [InlineData(&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;0:05&quot;</span>)] [InlineData(&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;1:20&quot;</span>)] [InlineData(&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;0:12:10&quot;</span>)] [InlineData(&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;1:00:12&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;1.13:14:34&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">CompositionLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;TimeSpan.Parse; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TimeSpan,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;(<span style="color:blue;">int</span>)ts.TotalMinutes; &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;g(f(s))).IsSatisfiedBy(input), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.ContraMap(g).ContraMap(f).IsSatisfiedBy(input)); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Once more, you can't directly compare methods for equality, so instead you have to call <code>IsSatisfiedBy</code> on both compositions to verify that they return the same Boolean value. </p> <p> They do. </p> <h3 id="94ecc00ea3064f86b48c45d0e9627cc8"> Product inventory specification <a href="#94ecc00ea3064f86b48c45d0e9627cc8" title="permalink">#</a> </h3> <p> You can now produce the desired <code>ISpecification&lt;ProductInventory&gt;</code> from the <code>NaturalNumber</code> Specification without having to add a new class: </p> <p> <pre>ISpecification&lt;ProductInventory&gt;&nbsp;<span style="color:#1f377f;">specification</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.ContraMap((ProductInventory&nbsp;<span style="color:#1f377f;">inv</span>)&nbsp;=&gt;&nbsp;inv.Quantity);</pre> </p> <p> Granted, it is, once more, a silly example, but the purpose of this article isn't to convince you that this is better (it probably isn't). The purpose of the article is to show an example of a contravariant functor, and how it can be used. </p> <h3 id="376573ff36c64561b5fc231589f6922f"> Predicates <a href="#376573ff36c64561b5fc231589f6922f" title="permalink">#</a> </h3> <p> For good measure, any predicate forms a contravariant functor. You don't need the <code>ISpecification</code> interface. Here are <code>ContraMap</code> overloads for <code>Predicate&lt;T&gt;</code> and <code>Func&lt;T, bool&gt;</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Predicate&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;(<span style="color:blue;">this</span>&nbsp;Predicate&lt;T&gt;&nbsp;<span style="color:#1f377f;">predicate</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;predicate(selector(x)); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;T1,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;T,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">predicate</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;predicate(selector(x)); }</pre> </p> <p> Notice that the lambda expressions are identical in both implementations. </p> <h3 id="4c2e7471713547d5a24a20dacce49806"> Conclusion <a href="#4c2e7471713547d5a24a20dacce49806" title="permalink">#</a> </h3> <p> Like Command Handlers and Event Handlers, generic predicates give rise to a contravariant functor. This includes both the Specification pattern, <code>Predicate&lt;T&gt;</code>, and <code>Func&lt;T, bool&gt;</code>. </p> <p> Are you noticing a pattern? </p> <p> <strong>Next:</strong> <a href="/2021/09/27/the-equivalence-contravariant-functor">The Equivalence contravariant functor</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. The Command Handler contravariant functor https://blog.ploeh.dk/2021/09/06/the-command-handler-contravariant-functor 2021-09-06T05:46:00+00:00 Mark Seemann <div id="post"> <p> <em>An introduction to the Command Handler contravariant functor for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction. </p> <p> Asynchronous software architectures, such as those described in <a href="http://bit.ly/eipatterns">Enterprise Integration Patterns</a>, often make good use of a pattern where <em>Commands</em> are (preferably immutable) <a href="https://en.wikipedia.org/wiki/Data_transfer_object">Data Transfer Objects</a> (DTOs) that are often placed on a persistent queue and later handled by a background process. </p> <p> Even if you don't use asynchronous processing, separating command data from command handling can be beneficial for your software's granular architecture. In perhaps his most remarkable contribution to <a href="/dippp">our book</a>, <a href="https://blogs.cuttingedge.it/steven">Steven van Deursen</a> describes how this pattern can greatly simplify how you deal with cross-cutting concerns. </p> <h3 id="3d338bea6fa74d149b239067a283967c"> Interface <a href="#3d338bea6fa74d149b239067a283967c" title="permalink">#</a> </h3> <p> In <a href="/dippp">DIPPP</a> the interface is called <code>ICommandService</code>, but in this article I'll instead call it <code>ICommandHandler</code>. It's a generic interface with a single method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">ICommandHandler</span>&lt;<span style="color:#2b91af;">TCommand</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(TCommand&nbsp;<span style="color:#1f377f;">command</span>); }</pre> </p> <p> The book explains how this interface enables you to gracefully handle cross-cutting concerns without any reflection magic. You can also peruse <a href="https://github.com/DependencyInjection-2nd-edition/codesamples">its example code base on GitHub</a>. In this article, however, I'm using <a href="https://github.com/ploeh/codesamples">a fork of that code</a> because I wanted to make the properties of contravariant functors stand out more clearly. </p> <p> In the sample code base, an ASP.NET Controller delegates work to an injected <code>ICommandHandler&lt;AdjustInventory&gt;</code> called <code>inventoryAdjuster</code>. </p> <p> <pre>[Route(<span style="color:#a31515;">&quot;inventory/adjustinventory&quot;</span>)] <span style="color:blue;">public</span>&nbsp;ActionResult&nbsp;<span style="color:#74531f;">AdjustInventory</span>(AdjustInventoryViewModel&nbsp;<span style="color:#1f377f;">viewModel</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!<span style="color:blue;">this</span>.ModelState.IsValid) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">this</span>.View(nameof(Index),&nbsp;<span style="color:blue;">this</span>.Populate(viewModel)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>&nbsp;=&nbsp;viewModel.Command; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.inventoryAdjuster.Execute(command); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.TempData[<span style="color:#a31515;">&quot;SuccessMessage&quot;</span>]&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Inventory&nbsp;successfully&nbsp;adjusted.&quot;</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">this</span>.RedirectToAction(nameof(HomeController.Index),&nbsp;<span style="color:#a31515;">&quot;Home&quot;</span>); }</pre> </p> <p> There's a single implementation of <code>ICommandHandler&lt;AdjustInventory&gt;</code>, which is a class called <code>AdjustInventoryService</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">AdjustInventoryService</span>&nbsp;:&nbsp;ICommandHandler&lt;AdjustInventory&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IInventoryRepository&nbsp;repository; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">AdjustInventoryService</span>(IInventoryRepository&nbsp;<span style="color:#1f377f;">repository</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(repository&nbsp;==&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(repository)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository&nbsp;=&nbsp;repository; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantityAdjustment</span>&nbsp;=&nbsp;command.Quantity&nbsp;*&nbsp;(command.Decrease&nbsp;?&nbsp;-1&nbsp;:&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.AdjustQuantity(quantityAdjustment); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(productInventory.Quantity&nbsp;&lt;&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;InvalidOperationException(<span style="color:#a31515;">&quot;Can&#39;t&nbsp;decrease&nbsp;below&nbsp;0.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The <code>Execute</code> method first loads the inventory data from the database, calculates how to adjust it, and saves it. This is all fine and good object-oriented design, and my intent with the present article isn't to point fingers at it. My intent is only to demonstrate how the <code>ICommandHandler</code> interface gives rise to a contravariant functor. </p> <p> I'm using this particular code base because it provides a good setting for a realistic example. </p> <h3 id="24bc8cde80ca4234b4eea11c7617a784"> Towards Domain-Driven Design <a href="#24bc8cde80ca4234b4eea11c7617a784" title="permalink">#</a> </h3> <p> Consider these two lines of code from <code>AdjustInventoryService</code>: </p> <p> <pre><span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantityAdjustment</span>&nbsp;=&nbsp;command.Quantity&nbsp;*&nbsp;(command.Decrease&nbsp;?&nbsp;-1&nbsp;:&nbsp;1); productInventory&nbsp;=&nbsp;productInventory.AdjustQuantity(quantityAdjustment);</pre> </p> <p> Doesn't that look like a case of <a href="https://wiki.c2.com/?FeatureEnvySmell">Feature Envy</a>? Doesn't this calculation belong better on another class? Which one? The <code>AdjustInventory</code> Command? That's one option, but in this style of architecture Commands are supposed to be dumb DTOs, so that may not be the best fit. <code>ProductInventory</code>? That may be more promising. </p> <p> Before making that change, however, let's consider the current state of the class. </p> <p> One of the changes I made in my fork of the code was to turn the <code>ProductInventory</code> class into an immutable <a href="https://martinfowler.com/bliki/ValueObject.html">Value Object</a>, as recommended in <a href="http://amzn.to/WBCwx7">DDD</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ProductInventory</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ProductInventory</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>)&nbsp;:&nbsp;<span style="color:blue;">this</span>(id,&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ProductInventory</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantity</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;id; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;quantity; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Guid&nbsp;Id&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">int</span>&nbsp;Quantity&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;ProductInventory&nbsp;<span style="color:#74531f;">WithQuantity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">newQuantity</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(Id,&nbsp;newQuantity); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;ProductInventory&nbsp;<span style="color:#74531f;">AdjustQuantity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">adjustment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;WithQuantity(Quantity&nbsp;+&nbsp;adjustment); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;ProductInventory&nbsp;<span style="color:#1f377f;">inventory</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id.Equals(inventory.Id)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;==&nbsp;inventory.Quantity; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;HashCode.Combine(Id,&nbsp;Quantity); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> That looks like a lot of code, but keep in mind that <a href="/2018/09/17/typing-is-not-a-programming-bottleneck">typing isn't the bottleneck</a> - and besides, most of that code was written by various Visual Studio <em>Quick Actions</em>. </p> <p> Let's try to add a <code>Handle</code> method to <code>ProductInventory</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;ProductInventory&nbsp;<span style="color:#74531f;">Handle</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">adjustment</span>&nbsp;=&nbsp;command.Quantity&nbsp;*&nbsp;(command.Decrease&nbsp;?&nbsp;-1&nbsp;:&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;AdjustQuantity(adjustment); }</pre> </p> <p> While <code>AdjustInventoryService</code> isn't too difficult to unit test, it still does require setting up and configuring some <a href="https://martinfowler.com/bliki/TestDouble.html">Test Doubles</a>. The new method, on the other hand, is actually a <a href="https://en.wikipedia.org/wiki/Pure_function">pure function</a>, which means that <a href="/2015/05/07/functional-design-is-intrinsically-testable">it's trivial to unit test</a>: </p> <p> <pre>[Theory] [InlineData(0,&nbsp;<span style="color:blue;">false</span>,&nbsp;0,&nbsp;0)] [InlineData(0,&nbsp;&nbsp;<span style="color:blue;">true</span>,&nbsp;0,&nbsp;0)] [InlineData(0,&nbsp;<span style="color:blue;">false</span>,&nbsp;1,&nbsp;1)] [InlineData(0,&nbsp;<span style="color:blue;">false</span>,&nbsp;2,&nbsp;2)] [InlineData(1,&nbsp;<span style="color:blue;">false</span>,&nbsp;1,&nbsp;2)] [InlineData(2,&nbsp;<span style="color:blue;">false</span>,&nbsp;3,&nbsp;5)] [InlineData(5,&nbsp;&nbsp;<span style="color:blue;">true</span>,&nbsp;2,&nbsp;3)] [InlineData(5,&nbsp;&nbsp;<span style="color:blue;">true</span>,&nbsp;5,&nbsp;0)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Handle</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">initial</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#1f377f;">decrease</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">adjustment</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(Guid.NewGuid(),&nbsp;initial); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">command</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;AdjustInventory &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProductId&nbsp;=&nbsp;sut.Id, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Decrease&nbsp;=&nbsp;decrease, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;adjustment &nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.Handle(command); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(sut.WithQuantity(expected),&nbsp;actual); }</pre> </p> <p> Now that the new function is available on <code>ProductInventory</code>, you can use it in <code>AdjustInventoryService</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.Handle(command); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(productInventory.Quantity&nbsp;&lt;&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;InvalidOperationException(<span style="color:#a31515;">&quot;Can&#39;t&nbsp;decrease&nbsp;below&nbsp;0.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory); }</pre> </p> <p> The <code>Execute</code> method now delegates its central logic to <code>ProductInventory.Handle</code>. </p> <h3 id="ee1b47388e1340a9ac8ced8eb3d7a181"> Encapsulation <a href="#ee1b47388e1340a9ac8ced8eb3d7a181" title="permalink">#</a> </h3> <p> If you consider the <code>Execute</code> method in its current incarnation, you may wonder why it checks whether the <code>Quantity</code> is negative. Shouldn't that be the responsibility of <code>ProductInventory</code>? Why do we even allow <code>ProductInventory</code> to enter an invalid state? </p> <p> This breaks encapsulation. Encapsulation is one of the most misunderstood concepts in programming, but as <a href="/encapsulation-and-solid">I explain in my PluralSight course</a>, as a minimum requirement, an object should not allow itself to be put into an invalid state. </p> <p> How to better encapsulate <code>ProductInventory</code>? Add a Guard Clause to the constructor: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ProductInventory</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantity</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(quantity&nbsp;&lt;&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentOutOfRangeException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(quantity), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;Negative&nbsp;quantity&nbsp;not&nbsp;allowed.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;id; &nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;quantity; }</pre> </p> <p> Again, such behaviour is trivial to drive with a unit test: </p> <p> <pre>[Theory] [InlineData(&nbsp;-1)] [InlineData(&nbsp;-2)] [InlineData(-19)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">SetNegativeQuantity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">negative</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">id</span>&nbsp;=&nbsp;Guid.NewGuid(); &nbsp;&nbsp;&nbsp;&nbsp;Action&nbsp;<span style="color:#1f377f;">action</span>&nbsp;=&nbsp;()&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(id,&nbsp;negative); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Throws&lt;ArgumentOutOfRangeException&gt;(action); }</pre> </p> <p> With those changes in place, <code>AdjustInventoryService</code> becomes even simpler: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.Handle(command); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory); }</pre> </p> <p> Perhaps even so simple that the class begins to seem unwarranted. </p> <h3 id="6f41a860c47741d7b2eb3b4b720d1d7f"> Sandwich <a href="#6f41a860c47741d7b2eb3b4b720d1d7f" title="permalink">#</a> </h3> <p> It's just a database Query, a single pure function call, and another database Command. In fact, it looks a lot like an <a href="/2020/03/02/impureim-sandwich">impureim sandwich</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { <span style="background-color: lightsalmon;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId)</span> <span style="background-color: palegreen;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.Handle(command);</span> <span style="background-color: lightsalmon;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory);</span> }</pre> </p> <p> In fact, it'd probably be more appropriate to move the null-handling closer to the other <a href="https://en.wikipedia.org/wiki/Referential_transparency">referentially transparent</a> code: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { <span style="background-color: lightsalmon;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId);</span> <span style="background-color: palegreen;">&nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(productInventory&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command);</span> <span style="background-color: lightsalmon;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory);</span> }</pre> </p> <p> Why do we need the <code>AdjustInventoryService</code> class, again? </p> <p> Can't we move those three lines of code to the Controller? We could, but that might make testing the above <code>AdjustInventory</code> Controller action more difficult. After all, at the moment, the Controller has an injected <code>ICommandHandler&lt;AdjustInventory&gt;</code>, which is easy to replace with a Test Double. </p> <p> If only we could somehow <em>compose</em> an <code>ICommandHandler&lt;AdjustInventory&gt;</code> from the above sandwich <em>without having to define a class</em>... </p> <h3 id="535cefbfe8564f888f92fa4edd1fe7c8"> Contravariant functor <a href="#535cefbfe8564f888f92fa4edd1fe7c8" title="permalink">#</a> </h3> <p> Fortunately, an interface like <code>ICommandHandler&lt;T&gt;</code> gives rise to a contravariant functor. This will enable you to compose an <code>ICommandHandler&lt;AdjustInventory&gt;</code> object from the above constituent parts. </p> <p> In order to enable contravariant mapping, you must add a <code>ContraMap</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ICommandHandler&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;ICommandHandler&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Action&lt;T1&gt;&nbsp;<span style="color:#1f377f;">action</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;source.Execute(selector(x)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;T1&gt;(action); }</pre> </p> <p> Notice that, as explained in the overview article, in order to map from an <code>ICommandHandler&lt;T&gt;</code> to an <code>ICommandHandler&lt;T1&gt;</code>, the <code>selector</code> has to go the other way: from <code>T1</code> to <code>T</code>. How this is possible will become more apparent with an example, which will follow later in the article. </p> <p> The <code>ContraMap</code> method uses a <code>DelegatingCommandHandler</code> that wraps any <code>Action&lt;T&gt;</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">DelegatingCommandHandler</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;:&nbsp;ICommandHandler&lt;T&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Action&lt;T&gt;&nbsp;action; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">DelegatingCommandHandler</span>(Action&lt;T&gt;&nbsp;<span style="color:#1f377f;">action</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.action&nbsp;=&nbsp;action; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(T&nbsp;<span style="color:#1f377f;">command</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action(command); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> If you're now wondering whether <code>Action&lt;T&gt;</code> itself gives rise to a contravariant functor, then yes it does. </p> <h3 id="cab26cece052462890c8e04363a907ec"> Identity law <a href="#cab26cece052462890c8e04363a907ec" title="permalink">#</a> </h3> <p> A <code>ContraMap</code> method with the right signature isn't enough to be a contravariant functor. It must also obey the contravariant functor laws. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the identity law for the <code>ICommandHandler&lt;T&gt;</code> interface. In this article, you'll see parametrised tests written with <a href="https://xunit.net">xUnit.net</a>. First, the identity law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;baz&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;qux&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;quux&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;quuz&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;corge&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;grault&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;garply&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">observations</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;List&lt;<span style="color:blue;">string</span>&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;<span style="color:blue;">string</span>&gt;(observations.Add); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;sut.ContraMap&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">string</span>&gt;(id); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Run&nbsp;both&nbsp;handlers</span> &nbsp;&nbsp;&nbsp;&nbsp;sut.Execute(input); &nbsp;&nbsp;&nbsp;&nbsp;projection.Execute(input); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(2,&nbsp;observations.Count); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Single(observations.Distinct()); }</pre> </p> <p> In order to observe that the two handlers have identical behaviours, the test has to <code>Execute</code> both of them to verify that both observations are the same. </p> <p> All test cases pass. </p> <h3 id="b4000e7978f949d8817590b0779d0afe"> Composition law <a href="#b4000e7978f949d8817590b0779d0afe" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>ContraMap</code> obeys the composition law for contravariant functors: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;baz&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;qux&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;quux&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;quuz&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;corge&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;grault&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;garply&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">CompositionLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">observations</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;List&lt;TimeSpan&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;TimeSpan&gt;(observations.Add); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;TimeSpan.FromDays(i); &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">projection1</span>&nbsp;=&nbsp;sut.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;g(f(s))); &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">projection2</span>&nbsp;=&nbsp;sut.ContraMap(g).ContraMap(f); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Run&nbsp;both&nbsp;handlers</span> &nbsp;&nbsp;&nbsp;&nbsp;projection1.Execute(input); &nbsp;&nbsp;&nbsp;&nbsp;projection2.Execute(input); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(2,&nbsp;observations.Count); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Single(observations.Distinct()); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Once more, you can't directly compare methods for equality, so instead you have to <code>Execute</code> them to verify that they produce the same observable effect. </p> <p> They do. </p> <h3 id="a068d2c54eda4315a4c592aa30b998f4"> Composed inventory adjustment handler <a href="#a068d2c54eda4315a4c592aa30b998f4" title="permalink">#</a> </h3> <p> We can now return to the inventory adjustment example. You may recall that the Controller would <code>Execute</code> a <code>command</code> on an injected <code>ICommandHandler&lt;AdjustInventory&gt;</code>: </p> <p> <pre><span style="color:blue;">this</span>.inventoryAdjuster.Execute(command);</pre> </p> <p> As a first step, we can attempt to compose <code>inventoryAdjuster</code> on the fly: </p> <p> <pre>ICommandHandler&lt;AdjustInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((ProductInventory&nbsp;<span style="color:#1f377f;">inv</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inv&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((AdjustInventory&nbsp;<span style="color:#1f377f;">cmd</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repository.GetByIdOrNull(cmd.ProductId)); inventoryAdjuster.Execute(command);</pre> </p> <p> Contra-mapping is hard to get one's head around, and to make matters worse, you have to read it from the bottom towards the top to understand what it does. It really is contrarian. </p> <p> How do you arrive at something like this? </p> <p> You start by looking at what you have. The Controller may already have an injected <code>repository</code> with various methods. <code>repository.Save</code>, for example, has this signature: </p> <p> <pre><span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Save</span>(ProductInventory&nbsp;<span style="color:#1f377f;">productInventory</span>);</pre> </p> <p> Since it has a <code>void</code> return type, you can treat <code>repository.Save</code> as an <code>Action&lt;ProductInventory&gt;</code>. Wrap it in a <code>DelegatingCommandHandler</code> and you have an <code>ICommandHandler&lt;ProductInventory&gt;</code>: </p> <p> <pre>ICommandHandler&lt;ProductInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save);</pre> </p> <p> That's not what you need, though. You need an <code>ICommandHandler&lt;AdjustInventory&gt;</code>. How do you get closer to that? </p> <p> You already know from the <code>AdjustInventoryService</code> class that you can use a pure function as the core of the impureim sandwich. Try that and see what it gives you: </p> <p> <pre>ICommandHandler&lt;ProductInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((ProductInventory&nbsp;<span style="color:#1f377f;">inv</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inv&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command));</pre> </p> <p> That doesn't change the type of the handler, but implements the desired functionality. </p> <p> You have an <code>ICommandHandler&lt;ProductInventory&gt;</code> that you need to somehow map to an <code>ICommandHandler&lt;AdjustInventory&gt;</code>. How do you do that? </p> <p> By supplying a function that goes the other way: from <code>AdjustInventory</code> to <code>ProductInventory</code>. Does such a method exist? Yes, it does, on the repository: </p> <p> <pre>ProductInventory&nbsp;<span style="color:#74531f;">GetByIdOrNull</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>);</pre> </p> <p> Or, close enough. While <code>AdjustInventory</code> is not a <code>Guid</code>, it <em>comes with</em> a <code>Guid</code>: </p> <p> <pre>ICommandHandler&lt;AdjustInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((ProductInventory&nbsp;<span style="color:#1f377f;">inv</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inv&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((AdjustInventory&nbsp;<span style="color:#1f377f;">cmd</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repository.GetByIdOrNull(cmd.ProductId));</pre> </p> <p> That's cool, but unfortunately, this composition cheats. It closes over <code>command</code>, which is a run-time variable only available inside the <code>AdjustInventory</code> Controller action. </p> <p> If we're allowed to compose the Command Handler <em>inside</em> the <code>AdjustInventory</code> method, we might as well just have written: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">inv</span>&nbsp;=&nbsp;repository.GetByIdOrNull(command.ProductId); inv&nbsp;=&nbsp;(inv&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command); repository.Save(inv);</pre> </p> <p> This is clearly much simpler, so why don't we do that? </p> <p> In this particular example, that's probably a better idea overall, but I'm trying to explain what is possible with contravariant functors. The goal here is to decouple the caller (the Controller) from the handler. We want to be able to define the handler outside of the Controller action. </p> <p> That's what the <code>AdjustInventory</code> class does, but can we leverage the contravariant functor to compose an <code>ICommandHandler&lt;AdjustInventory&gt;</code> <em>without</em> adding a new class? </p> <h3 id="01c3971cdf1d43ca8fd5db6005477304"> Composition without closures <a href="#01c3971cdf1d43ca8fd5db6005477304" title="permalink">#</a> </h3> <p> The use of a closure in the above composition is what disqualifies it. Is it possible to compose an <code>ICommandHandler&lt;AdjustInventory&gt;</code> when the <code>command</code> object is unavailable to close over? </p> <p> Yes, but it isn't pretty: </p> <p> <pre>ICommandHandler&lt;AdjustInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((ValueTuple&lt;AdjustInventory,&nbsp;ProductInventory&gt;&nbsp;<span style="color:#1f377f;">t</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(t.Item2&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(t.Item1.ProductId)).Handle(t.Item1)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((AdjustInventory&nbsp;<span style="color:#1f377f;">cmd</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cmd,&nbsp;repository.GetByIdOrNull(cmd.ProductId)));</pre> </p> <p> You can let the composing function return a tuple of the original input value <em>and</em> the projected value. That's what the lowest <code>ContraMap</code> does. This means that the upper <code>ContraMap</code> receives this tuple to map. Not pretty, but possible. </p> <p> I never said that this was the <em>best</em> way to address some of the concerns I've hinted at in this article. The purpose of the article was mainly to give you a sense of what a contravariant functor can do. </p> <h3 id="0a960dd6e8f24121a5b9229b9cca1e7a"> Action as a contravariant functor <a href="#0a960dd6e8f24121a5b9229b9cca1e7a" title="permalink">#</a> </h3> <p> Wrapping an <code>Action&lt;T&gt;</code> in a <code>DelegatingCommandHandler</code> isn't necessary in order to form the contravariant functor. I only used the <code>ICommandHandler</code> interface as an object-oriented-friendly introduction to the example. In fact, any <code>Action&lt;T&gt;</code> gives rise to a contravariant functor with this <code>ContraMap</code> function: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Action&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;(<span style="color:blue;">this</span>&nbsp;Action&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;source(selector(x)); }</pre> </p> <p> As you can tell, the function being returned is similar to the lambda expression used to implement <code>ContraMap</code> for <code>ICommandHandler&lt;T&gt;</code>. </p> <p> This turns out to make little difference in the context of the examples shown here, so I'm not going to tire you with more example code. </p> <h3 id="9c7dc6d88a164a0b8bd7ac06eea22dc4"> Conclusion <a href="#9c7dc6d88a164a0b8bd7ac06eea22dc4" title="permalink">#</a> </h3> <p> Any generic polymorphic interface or abstract method with a <code>void</code> return type gives rise to a contravariant functor. This includes the <code>ICommandHandler&lt;T&gt;</code> (originally <code>ICommandService&lt;T&gt;</code>) interface, but also another interface discussed in <a href="/dippp">DIPPP</a>: <code>IEventHandler&lt;TEvent&gt;</code>. </p> <p> The utility of this insight may not be immediately apparent. Contrary to its built-in support for functors, C# doesn't have any language features that light up if you implement a <code>ContraMap</code> function. Even in <a href="https://www.haskell.org">Haskell</a> where <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">the Contravariant functor is available in the <em>base</em> library</a>, I can't recall having ever used it. </p> <p> Still, even if not a <em>practical</em> insight, the ubiquitous presence of contravariant functors in everyday programming 'building blocks' tells us something profound about the fabric of programming abstraction and polymorphism. </p> <p> <strong>Next:</strong> <a href="/2021/09/09/the-specification-contravariant-functor">The Specification contravariant functor</a>. </p> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Contravariant functors https://blog.ploeh.dk/2021/09/02/contravariant-functors 2021-09-02T06:49:00+00:00 Mark Seemann <div id="post"> <p> <em>A more exotic kind of universal abstraction.</em> </p> <p> This article series is part of <a href="/2018/03/19/functors-applicatives-and-friends">a larger series of articles about functors, applicatives, and other mappable containers</a>. </p> <p> So far in the article series, you've seen examples of mappable containers that map in the same direction of projections, so to speak. Let's unpack that. </p> <h3 id="272009219c12482cba296186e0e0a645"> Covariance recap <a href="#272009219c12482cba296186e0e0a645" title="permalink">#</a> </h3> <p> <a href="/2018/03/22/functors">Functors</a>, <a href="/2018/10/01/applicative-functors">applicative functors</a>, and <a href="/2018/12/24/bifunctors">bifunctors</a> all follow the direction of projections. Consider the illustration from <a href="/2018/03/22/functors">the article about functors</a>: </p> <p> <img src="/content/binary/functor-diagram.png" alt="Functor diagram."> </p> <p> The function <code>f</code> maps from <code>a</code> to <code>b</code>. You can think of <code>a</code> and <code>b</code> as two types, or two sets. For example, if <code>a</code> is the set of all strings, it might correspond to the type <code>String</code>. Likewise, if <code>b</code> is the set of all integers, then it corresponds to a type called <code>Int</code>. The function <code>f</code> would, in that case, have the type <code>String -&gt; Int</code>; that is: it maps strings to integers. The most natural such function seems to be one that counts the number of characters in a string: </p> <p> <pre>&gt; f = length &gt; f "foo" 3 &gt; f "ploeh" 5</pre> </p> <p> This little interactive session uses <a href="https://www.haskell.org">Haskell</a>, but even if you've never heard about Haskell before, you should still be able to understand what's going on. </p> <p> A functor is a <a href="https://bartoszmilewski.com/2014/01/14/functors-are-containers">container</a> of values, for example a collection, a <a href="/2018/03/26/the-maybe-functor">Maybe</a>, a <a href="/2018/09/10/the-lazy-functor">lazy computation</a>, or many other things. If <code>f</code> maps from <code>a</code> to <code>b</code>, then lifting it to the functor <code>F</code> retains the direction. That's what the above figure illustrates. Not only does the functor project <code>a</code> to <code>F a</code> and <code>b</code> to <code>F b</code>, it also maps <code>f</code> to <code>F f</code>, which is <code>F a -&gt; F b</code>. </p> <p> For lists it might look like this: </p> <p> <pre>&gt; fmap f ["bar", "fnaah", "Gauguin"] [3,5,7]</pre> </p> <p> Here <code>fmap</code> lifts the function <code>String -&gt; Int</code> to <code>[String] -&gt; [Int]</code>. Notice that the types 'go in the same direction' when you lift a function to the functor. The types vary <em>with</em> the function - they <em>co</em>-vary; hence <em>covariance</em>. </p> <p> While applicative functors and bifunctors are more complex, they are still covariant. Consult, for example, the diagrams in my <a href="/2018/12/24/bifunctors">bifunctor article</a> to get an intuitive sense that this still holds. </p> <h3 id="187c2160ddf94c119c341534189d3eab"> Contravariance <a href="#187c2160ddf94c119c341534189d3eab" title="permalink">#</a> </h3> <p> What happens if we change the direction of <em>only one</em> arrow? For example, we could change the direction of the <code>f</code> arrow, so that the function is now a function from <code>b</code> to <code>a</code>: <code>b -&gt; a</code>. The figure would look like this: </p> <p> <img src="/content/binary/contravariant-functor-diagram.png" alt="Contravariant functor diagram."> </p> <p> This looks <em>almost</em> like the first figure, with one crucial difference: The lower arrow now goes from right to left. Notice that the upper arrow still goes from left to right: <code>F a -&gt; F b</code>. In other words, the functor varies in the contrary direction than the projected function. It's <em>contravariant</em>. </p> <p> This seems really odd. Why would anyone do that? </p> <p> As is so often the case with universal abstractions, it's not so much a question of coming up with an odd concept and see what comes of it. It's actually an abstract description of some common programming constructs. In this series of articles, you'll see examples of some contravariant functors: </p> <ul> <li><a href="/2021/09/06/the-command-handler-contravariant-functor">The Command Handler contravariant functor</a></li> <li><a href="/2021/09/09/the-specification-contravariant-functor">The Specification contravariant functor</a></li> <li><a href="/2021/09/27/the-equivalence-contravariant-functor">The Equivalence contravariant functor</a></li> <li><a href="/2021/10/04/reader-as-a-contravariant-functor">Reader as a contravariant functor</a></li> <li><a href="/2021/10/25/functor-variance-compared-to-cs-notion-of-variance">Functor variance compared to C#'s notion of variance</a></li> <li><a href="/2022/03/21/contravariant-dependency-injection">Contravariant Dependency Injection</a></li> </ul> <p> These aren't the only examples, but they should be enough to get the point across. Other examples include equivalence and comparison. </p> <h3 id="b7b1780cc7a74ffaace2a42f06301561"> Lifting <a href="#b7b1780cc7a74ffaace2a42f06301561" title="permalink">#</a> </h3> <p> How do you lift a function <code>f</code> to a contravariant functor? For covariant functors (normally just called <em>functors</em>), Haskell has the <code>fmap</code> function, while in C# you'd be writing a family of <code>Select</code> methods. Let's compare. In Haskell, <code>fmap</code> has this type: </p> <p> <pre>fmap :: Functor f =&gt; (a -&gt; b) -&gt; f a -&gt; f b</pre> </p> <p> You can read it like this: For any <code>Functor f</code>, <code>fmap</code> lifts a function of the type <code>a -&gt; b</code> to a function of the type <code>f a -&gt; f b</code>. Another way to read this is that given a function <code>a -&gt; b</code> and a container of type <code>f a</code>, you can produce a container of type <code>f b</code>. Due to <a href="https://en.wikipedia.org/wiki/Currying">currying</a>, these two interpretations are both correct. </p> <p> In C#, you'd be writing a <a href="/2018/03/22/functors">method on <code>Functor&lt;T&gt;</code> that looks like this</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Functor</span>&lt;<span style="color:#2b91af;">TResult</span>&gt;&nbsp;Select&lt;<span style="color:#2b91af;">TResult</span>&gt;(<span style="color:#2b91af;">Func</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;&nbsp;selector)</pre> </p> <p> This fits the later interpretation of <code>fmap</code>: Given an instance of <code>Functor&lt;T&gt;</code>, you can call <code>Select</code> with a <code>Func&lt;T, TResult&gt;</code> to produce a <code>Functor&lt;TResult&gt;</code>. </p> <p> What does the equivalent function look like for contravariant functors? Haskell <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">defines it</a> as: </p> <p> <pre>contramap :: Contravariant f =&gt; (b -&gt; a) -&gt; f a -&gt; f b</pre> </p> <p> You can read it like this: For any <code>Contravariant</code> functor <code>f</code>, <code>contramap</code> lifts a function <code>(b -&gt; a)</code> to a function from <code>f a</code> to <code>f b</code>. Or, in the alternative (but equally valid) interpretation that matches C# better, given a function <code>(b -&gt; a)</code> and an <code>f a</code>, you can produce an <code>f b</code>. </p> <p> In C#, you'd be writing a method on <code>Contravariant&lt;T&gt;</code> that looks like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Contravariant&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T1</span>&gt;(Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>)</pre> </p> <p> The actual generic type (here exemplified by <code>Contravariant&lt;T&gt;</code>) will differ, but the shape of the method will be the same. In order to map from <code>Contravariant&lt;T&gt;</code> to <code>Contravariant&lt;T1&gt;</code>, you need a function that <em>goes the other way</em>: <code>Func&lt;T1, T&gt;</code> goes from <code>T1</code> to <code>T</code>. </p> <p> In C#, the function name doesn't have to be <code>ContraMap</code>, since C# doesn't have any built-in understanding of contravariant functors - as opposed to functors, where a method called <code>Select</code> will light up some language features. In this article series I'll stick with <code>ContraMap</code> since I couldn't think of a better name. </p> <h3 id="72905e6e48a343e1bf78deae36be0abf"> Laws <a href="#72905e6e48a343e1bf78deae36be0abf" title="permalink">#</a> </h3> <p> Like functors, applicative functors, <a href="/2017/10/06/monoids">monoids</a>, and other universal abstractions, contravariant functors are characterised by simple laws. The contravariant functor laws are equivalent to the (covariant) <a href="/2018/03/22/functors">functor laws</a>: <em>identity</em> and <em>composition</em>. </p> <p> In pseudo-Haskell, we can express the <em>identity</em> law as: </p> <p> <pre>contramap id = id</pre> </p> <p> and the <em>composition</em> law as: </p> <p> <pre>contramap (g . f) = contramap f . contramap g</pre> </p> <p> The <em>identity</em> law is equivalent to the first functor law. It states that mapping a contravariant functor with the identity function is equivalent to a no-op. The <em>identity function</em> is a function that returns all input unchanged. (It's called the <em>identity function</em> because it's the <em>identity</em> for the <a href="/2017/11/13/endomorphism-monoid">endomorphism monoid</a>.) In <a href="https://fsharp.org">F#</a> and Haskell, this is simply a built-in function called <code>id</code>. </p> <p> In C#, you can write a demonstration of the law as a unit test. Here's the essential part of such a test: </p> <p> <pre>Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">id</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x; Contravariant&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;createContravariant(); Assert.Equal(sut,&nbsp;sut.ContraMap(id),&nbsp;comparer);</pre> </p> <p> The <code>ContraMap</code> method <em>does</em> return a new object, so a custom <code>comparer</code> is required to evaluate whether <code>sut</code> is equal to <code>sut.ContraMap(id)</code>. </p> <p> The <em>composition</em> law governs how composition works. Again, notice how lifting reverses the order of functions. In C#, the relevant unit test code might look like this: </p> <p> <pre>Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; Func&lt;<span style="color:blue;">int</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;TimeSpan.FromDays(i); Contravariant&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;createContravariant(); Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;sut.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;g(f(s))), &nbsp;&nbsp;&nbsp;&nbsp;sut.ContraMap(g).ContraMap(f), &nbsp;&nbsp;&nbsp;&nbsp;comparer);</pre> </p> <p> This may actually look less surprising in C# than it does in Haskell. Here the lifted composition doesn't look reversed, but that's because C# doesn't have a composition operator for raw functions, so I instead wrote it as a lambda expression: <code>(string&nbsp;s)&nbsp;=&gt;&nbsp;g(f(s))</code>. If you contrast this C# example with the equivalent assertion of the (covariant) second functor law, you can see that the function order is flipped: <code>f(g(i))</code>. </p> <p> <pre><span style="color:#2b91af;">Assert</span>.Equal(sut.Select(g).Select(f),&nbsp;sut.Select(i&nbsp;=&gt;&nbsp;f(g(i))));</pre> </p> <p> It can be difficult to get your head around the order of contravariant composition without some examples. I'll provide examples in the following articles, but I wanted to leave the definition of the two contravariant functor laws here for reference. </p> <h3 id="68b342bda0ff41f5aec6fb7c08b299d3"> Conclusion <a href="#68b342bda0ff41f5aec6fb7c08b299d3" title="permalink">#</a> </h3> <p> Contravariant functors are functors that map in the opposite direction of an underlying function. This seems counter-intuitive but describes the actual behaviour of quite normal functions. </p> <p> This is hardly illuminating without some examples, so without further ado, let's proceed to the first one. </p> <p> <strong>Next:</strong> <a href="/2021/09/06/the-command-handler-contravariant-functor">The Command Handler contravariant functor</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. The Reader functor https://blog.ploeh.dk/2021/08/30/the-reader-functor 2021-08-30T05:42:00+00:00 Mark Seemann <div id="post"> <p> <em>Normal functions form functors. An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2018/03/22/functors">an article series about functors</a>. In a <a href="/2018/03/26/the-maybe-functor">previous article</a> you saw, for example, how to implement the Maybe functor in C#. In this article, you'll see another functor example: <em>Reader</em>. </p> <p> The Reader functor is similar to the <a href="/2018/09/03/the-identity-functor">Identity functor</a> in the sense that it seems practically useless. If that's the case, then why care about it? </p> <p> As I wrote about the Identity functor: </p> <blockquote> "The inutility of Identity doesn't mean that it doesn't exist. The Identity functor exists, whether it's useful or not. You can ignore it, but it still exists. In C# or <a href="https://fsharp.org">F#</a> I've never had any use for it (although I've <a href="/2017/09/04/builder-as-identity">described it before</a>), while it turns out to be occasionally useful in <a href="https://www.haskell.org">Haskell</a>, where it's built-in. The value of Identity is language-dependent." </blockquote> <p> The same holds for Reader. It exists. Furthermore, it teaches us something important about ordinary functions. </p> <h3 id="1539ecc9bc504aa1a0cc090255777b1d"> Reader interface <a href="#1539ecc9bc504aa1a0cc090255777b1d" title="permalink">#</a> </h3> <p> Imagine the following interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReader</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;<span style="color:#74531f;">Run</span>(R&nbsp;<span style="color:#1f377f;">environment</span>); }</pre> </p> <p> An <code>IReader</code> object can produce a value of the type <code>A</code> when given a value of the type <code>R</code>. The input is typically called the <code>environment</code>. A Reader reads the environment and produces a value. A possible (although not particularly useful) implementation might be: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">GuidToStringReader</span>&nbsp;:&nbsp;IReader&lt;Guid,&nbsp;<span style="color:blue;">string</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">string</span>&nbsp;format; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">GuidToStringReader</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">format</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.format&nbsp;=&nbsp;format; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#74531f;">Run</span>(Guid&nbsp;<span style="color:#1f377f;">environment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;environment.ToString(format); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This may be a silly example, but it illustrates that a a simple class can implement a constructed version of the interface: <code>IReader&lt;Guid,&nbsp;string&gt;</code>. It also demonstrates that a class can take further arguments via its constructor. </p> <p> While the <code>IReader</code> interface only takes a single input argument, <a href="/2018/01/29/argument-list-isomorphisms">we know that an argument list is isomorphic to a parameter object or tuple</a>. Thus, <code>IReader</code> is equivalent to <em>every</em> possible function type - up to isomorphism, assuming that <a href="/2018/01/15/unit-isomorphisms">unit is also a value</a>. </p> <p> While the practical utility of the Reader functor may not be immediately apparent, it's hard to argue that it isn't ubiquitous. Every method is (with a bit of hand-waving) a Reader. </p> <h3 id="23b5c83bffef42a0ab0c95919fef0166"> Functor <a href="#23b5c83bffef42a0ab0c95919fef0166" title="permalink">#</a> </h3> <p> You can turn the <code>IReader</code> interface into a functor by adding an appropriate <code>Select</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IReader&lt;R,&nbsp;B&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">B</span>,&nbsp;<span style="color:#2b91af;">R</span>&gt;(<span style="color:blue;">this</span>&nbsp;IReader&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">reader</span>,&nbsp;Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;FuncReader&lt;R,&nbsp;B&gt;(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;selector(reader.Run(r))); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">FuncReader</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt;&nbsp;:&nbsp;IReader&lt;R,&nbsp;A&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;R,&nbsp;A&gt;&nbsp;func; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">FuncReader</span>(Func&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">func</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.func&nbsp;=&nbsp;func; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;A&nbsp;<span style="color:#74531f;">Run</span>(R&nbsp;<span style="color:#1f377f;">environment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;func(environment); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The implementation of <code>Select</code> requires a private class to capture the projected function. <code>FuncReader</code> is, however, an implementation detail. </p> <p> When you <code>Run</code> a Reader, the output is a value of the type <code>A</code>, and since <code>selector</code> is a function that takes an <code>A</code> value as input, you can use the output of <code>Run</code> as input to <code>selector</code>. Thus, the return type of the lambda expression <code>r =&gt; selector(reader.Run(r))</code> is <code>B</code>. Therefore, <code>Select</code> returns an <code>IReader&lt;R, B&gt;</code>. </p> <p> Here's an example of using the <code>Select</code> method to project an <code>IReader&lt;Guid, string&gt;</code> to <code>IReader&lt;Guid, int&gt;</code>: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">WrappedFunctorExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;Guid,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;GuidToStringReader(<span style="color:#a31515;">&quot;N&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;Guid,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">projected</span>&nbsp;=&nbsp;r.Select(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Count(<span style="color:#1f377f;">c</span>&nbsp;=&gt;&nbsp;c.IsDigit())); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">input</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Guid(<span style="color:#a31515;">&quot;{CAB5397D-3CF9-40BB-8CBD-B3243B7FDC23}&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(16,&nbsp;projected.Run(input)); }</pre> </p> <p> The expected result is <code>16</code> because the <code>input</code> <code>Guid</code> contains 16 digits (the numbers from 0 to 9). Count them if you don't believe me. </p> <p> As usual, you can also use query syntax: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">QuerySyntaxFunctorExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">projected</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;s&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:blue;">new</span>&nbsp;GuidToStringReader(<span style="color:#a31515;">&quot;N&quot;</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;TimeSpan.FromMinutes(s.Length); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">input</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Guid(<span style="color:#a31515;">&quot;{FE2AB9C6-DDB1-466C-8AAA-C70E02F964B9}&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(32,&nbsp;projected.Run(input).TotalMinutes); }</pre> </p> <p> The actual computation shown here makes little sense, since the result will always be <code>32</code>, but it illustrates that arbitrary projections are possible. </p> <h3 id="ad9b3abef16c4ec8a70a1263c17eecd6"> Raw functions <a href="#ad9b3abef16c4ec8a70a1263c17eecd6" title="permalink">#</a> </h3> <p> The <code>IReader&lt;R, A&gt;</code> interface isn't really necessary. It was just meant as an introduction to make things a bit easier for object-oriented programmers. You can write a similar <code>Select</code> extension method for any <code>Func&lt;R, A&gt;</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;R,&nbsp;B&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">B</span>,&nbsp;<span style="color:#2b91af;">R</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">func</span>,&nbsp;Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;selector(func(r)); }</pre> </p> <p> Compare this implementation to the one above. It's essentially the same lambda expression, but now <code>Select</code> returns the raw function instead of wrapping it in a class. </p> <p> In the following, I'll use raw functions instead of the <code>IReader</code> interface. </p> <h3 id="de5e5a6801ab49d4ae993181a05f7bab"> First functor law <a href="#de5e5a6801ab49d4ae993181a05f7bab" title="permalink">#</a> </h3> <p> The <code>Select</code> method obeys the first functor law. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the first functor law for the <code>IReader&lt;R, A&gt;</code> interface. In this article, you'll see parametrised tests written with <a href="https://xunit.net">xUnit.net</a>. First, the first functor law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;corge&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;antidisestablishmentarianism&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FirstFunctorLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;f.Select(id); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(f(input),&nbsp;actual(input)); }</pre> </p> <p> The 'original' Reader <code>f</code> (for <em>function</em>) takes a <code>string</code> as input and returns its length. The <code>id</code> function (which isn't built-in in C#) is implemented as a <a href="https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/local-functions">local function</a>. It returns whichever input it's given. </p> <p> Since <code>id</code> returns any input without modifying it, it'll also return any number produced by <code>f</code> without modification. </p> <p> To evaluate whether <code>f</code> is equal to <code>f.Select(id)</code>, the assertion calls both functions with the same input. If the functions have equal behaviour, they ought to return the same output. </p> <p> The above test cases all pass. </p> <h3 id="1dc17b41888b420d8b8161f9ef9fb84c"> Second functor law <a href="#1dc17b41888b420d8b8161f9ef9fb84c" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that a function (Reader) obeys the second functor law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;corge&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;antidisestablishmentarianism&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">SecondFunctorLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;i&nbsp;%&nbsp;2&nbsp;==&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">bool</span>,&nbsp;<span style="color:blue;">char</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">b</span>&nbsp;=&gt;&nbsp;b&nbsp;?&nbsp;<span style="color:#a31515;">&#39;t&#39;</span>&nbsp;:&nbsp;<span style="color:#a31515;">&#39;f&#39;</span>; &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h.Select(g).Select(f)(input), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h.Select(<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;f(g(i)))(input)); }</pre> </p> <p> You can't easily compare two different functions for equality, so, like above, this test defines equality as the functions producing the same result when you invoke them. </p> <p> Again, while the test doesn't <em>prove</em> anything, it demonstrates that for the five test cases, it doesn't matter if you project the 'original' Reader <code>h</code> in one or two steps. </p> <h3 id="76a34d3dfde1438abd080f02499bc344"> Haskell <a href="#76a34d3dfde1438abd080f02499bc344" title="permalink">#</a> </h3> <p> In Haskell, normal functions <code>a -&gt; b</code> are already <code>Functor</code> instances, which means that you can easily replicate the functions from the <code>SecondFunctorLaw</code> test: </p> <p> <pre>&gt; h = length &gt; g i = i `mod` 2 == 0 &gt; f b = if b then 't' else 'f' &gt; (fmap f $ fmap g $ h) "ploeh" 'f'</pre> </p> <p> Here <code>f</code>, <code>g</code>, and <code>h</code> are equivalent to their above C# namesakes, while the last line composes the functions stepwise and calls the composition with the input string <code>"ploeh"</code>. In Haskell you generally read code from right to left, so this composition corresponds to <code>h.Select(g).Select(f)</code>. </p> <h3 id="9d3006be0e904994b2285ae791fd287a"> Conclusion <a href="#9d3006be0e904994b2285ae791fd287a" title="permalink">#</a> </h3> <p> Functions give rise to functors, usually known collectively as the Reader functor. Even in Haskell where this fact is ingrained into the fabric of the language, I rarely make use of it. It just is. In C#, it's likely to be even less useful for practical programming purposes. </p> <p> That a function <code>a -&gt; b</code> forms a functor, however, is an important insight into just what a function actually is. It describes an essential property of functions. In itself this may still seem underwhelming, but mixed with some other properties (that I'll describe in <a href="/2021/10/04/reader-as-a-contravariant-functor">a future article</a>) it can produce some profound insights. So stay tuned. </p> <p> <strong>Next:</strong> <a href="/2020/06/22/the-io-functor">The IO functor</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Am I stuck in a local maximum? https://blog.ploeh.dk/2021/08/09/am-i-stuck-in-a-local-maximum 2021-08-09T05:56:00+00:00 Mark Seemann <div id="post"> <p> <em>On long-standing controversies, biases, and failures of communication.</em> </p> <p> If you can stay out of politics, Twitter can be a great place to engage in robust discussions. I mostly follow and engage with people in the programming community, and every so often find myself involved in a discussion about one of several long-standing controversies. No, not the tabs-versus-spaces debate, but other debates such as functional versus object-oriented programming, dynamic versus static typing, or <a href="/2020/03/16/conways-law-latency-versus-throughput">oral versus written collaboration</a>. </p> <p> It happened again the past week, but while this article is a reaction, it's not about the specific debacle. Thus, I'm not going to link to the tweets in question. </p> <p> These discussion usually leave me wondering why people with decades of industry experience seem to have such profound disagreements. </p> <h3 id="13c8dc8fbc9b4e26ba08bfeef9b61fd9"> I might be wrong <a href="#13c8dc8fbc9b4e26ba08bfeef9b61fd9" title="permalink">#</a> </h3> <p> Increasingly, I find myself disagreeing with my heroes. This isn't a comfortable position. Could I be wrong? </p> <p> I've definitely been wrong before. For example, in my article <a href="/2016/02/10/types-properties-software">Types + Properties = Software</a>, I wrote about type systems: </p> <blockquote> <p>"To the far right, we have a hypothetical language with such a strong type system that, indeed, <em>if it compiles, it works.</em>"</p> </blockquote> <p> <em>To the right</em>, in this context, means <em>more statically typed</em>. While the notion is natural, the sentence is uninformed. When I wrote the article, I <a href="https://www.goodreads.com/review/show/1731926050">hadn't yet read</a> Charles Petzold's excellent <a href="http://amzn.to/2n9MFGh">Annotated Turing</a>. Although I had heard about the <a href="https://en.wikipedia.org/wiki/Halting_problem">halting problem</a> before reading the book, I hadn't internalised it. I wasn't able to draw inferences based on that labelled concept. </p> <p> After I read the book, I've come to understand that general-purpose static type system can never prove unequivocally that a generic program works. That's what <a href="https://en.wikipedia.org/wiki/Alonzo_Church">Church</a>, <a href="https://en.wikipedia.org/wiki/Alan_Turing">Turing</a>, and <a href="https://en.wikipedia.org/wiki/Kurt_Gödel">Gödel</a> proved. </p> <p> I've been writing articles on this blog <a href="/2009/01/28/LivingInInterestingTimes">since January 2009</a>. To date, I've published 582 posts. Some are bound to be misinformed, outdated, or just plain wrong. Due to the sheer volume, I make no consistent effort to retroactively monitor and correct my past self. (I'm happy to engage with specific posts. If you feel that an old post is misleading, erroneous, or the like, please <a href="https://github.com/ploeh/ploeh.github.com#comments">leave a comment</a>.) </p> <p> For good measure, despite my failure to understand the implications of the halting problem, I'm otherwise happy with the article series <a href="/2016/02/10/types-properties-software">Types + Properties = Software</a>. You shouldn't consider this particular example a general condemnation of it. It's just an example of a mistake I made. This time, I'm aware of it, but there are bound to be plenty of other examples where I don't even realise it. </p> <h3 id="d7843f0140164eaf97a7724413d70d76"> Heroes <a href="#d7843f0140164eaf97a7724413d70d76" title="permalink">#</a> </h3> <p> I don't have a formal degree in computer science. As so many others of my age, I began my software career by tinkering with computers and (later) programming. The first five years of my professional career, there wasn't much methodology to the way I approached software development. Self-taught often means that you have to learn everything the hard way. </p> <p> This changed when I first heard about test-driven development (TDD). I credit <a href="https://martinfowler.com">Martin Fowler</a> with that. Around the same time I also read <a href="http://amzn.to/XBYukB">Design Patterns</a>. Armed with those two techniques, I was able to rescue a failed software project and bring it to successful completion. I even received an (internal) award for it. </p> <p> While there's more to skilled programming than test-driven development and patterns, it wasn't a bad place to start. Where, before, I had nothing that even resembled a methodology, now I had a set of practices I could use. This gave me an opportunity to experiment and observe. A few years later, <a href="/2010/12/03/Towardsbetterabstractions">I'd already started to notice some recurring beneficial patterns</a> in the code that I wrote, as well as <a href="/2010/12/22/TheTDDApostate">some limits of TDD</a>. </p> <p> Still, that was a decade where I voraciously read, attended conferences, and tried to learn from my heroes. I hope that they won't mind that I list them here: <ul> <li><a href="https://martinfowler.com">Martin Fowler</a></li> <li><a href="https://en.wikipedia.org/wiki/Kent_Beck">Kent Beck</a></li> <li><a href="https://en.wikipedia.org/wiki/Robert_C._Martin">Robert C. Martin</a></li> <li><a href="https://michaelfeathers.silvrback.com">Michael Feathers</a></li> <li><a href="https://dannorth.net">Dan North</a></li> </ul> Surely, there were others. I remember being a big fan of <a href="https://en.wikipedia.org/wiki/Don_Box">Don Box</a>, but he seems to have withdrawn from the public long time ago. There were also .NET trailblazers that I admired and tried to emulate. Later, I learned much from the early luminaries of <a href="https://fsharp.org">F#</a>. I'm not going to list all the people I admire here, because the list could never be complete, and I don't wish to leave anyone feeling left out. Related to the point I'm trying to make, all these other wonderful people give me less pause. </p> <p> There's a reason I list those particular heroes. I should include a few more of whom I wasn't aware in my formative years, but whom I've since come to highly respect: <a href="https://twitter.com/marick">Brian Marick</a> and <a href="https://jessitron.com">Jessica Kerr</a>. </p> <p> Why do I mention these heroes of mine? </p> <h3 id="ae81dde11de94f9fb223cf06377a22c4"> Bias <a href="#ae81dde11de94f9fb223cf06377a22c4" title="permalink">#</a> </h3> <p> Humans aren't as rational as we'd like to think. We all have plenty of <a href="https://en.wikipedia.org/wiki/Cognitive_bias">cognitive biases</a>. I'm aware of a few of mine, but I expect most of them to be hidden from me. Sometimes, it's easier to spot the bias in others. Perhaps, by spotting the bias in others, it reveals something about oneself? </p> <p> I increasingly find myself disagreeing with my heroes. One example is the long-standing controversy about static versus dynamic typing. </p> <p> I hope I'm not misrepresenting anyone, but the heroes I enumerate above seem to favour dynamic typing over static typing - some more strongly than others. This worries me. </p> <p> These are people who've taught me a lot; whose opinion I deeply respect, and yet I fail to grasp the benefit of dynamic typing. What are the benefits they gain from their preferred languages that I'm blind to? What am I missing? </p> <p> Whenever I find myself disagreeing with my heroes, I can't help question my own judgment. Am I biased? Yes, obviously, but in which way? What bias prohibits me from seeing the benefits that are so obvious to them? </p> <p> It's too easy to jump to conclusions - to erect a dichotomy: <ul> <li>My heroes are right, and I'm wrong</li> <li>My heroes are <em>all</em> wrong, and I'm right</li> </ul> The evidence doesn't seem to support the latter conclusion, but if the first is true, I still fail to understand <em>why</em> I'm wrong. </p> <p> I'm hoping that there's a more nuanced position to take - that the above is a <a href="https://en.wikipedia.org/wiki/False_dilemma">false dichotomy</a>. </p> <h3 id="1dc21ee0532e4555ab621dfd32f31f12"> What's the problem? <a href="#1dc21ee0532e4555ab621dfd32f31f12" title="permalink">#</a> </h3> <p> Perhaps we're really talking past each other. Perhaps we're trying to solve different problems, and thereby arrive at different solutions. </p> <p> I can only guess at the kinds of problems that my heroes think of when they prefer dynamic languages, and I don't want to misrepresent them. What I <em>can</em> do, however, is outline the kind of problem that I typically have in mind. </p> <p> I've spent much of my career trying to balance <a href="/2019/03/04/code-quality-is-not-software-quality">sustainability</a> with correctness. I consider correctness as a prerequisite for all code. As <a href="http://amzn.to/1jos26M">Gerald Weinberg implies</a>, if a program doesn't have to work, anything goes. Thus, sustainability is a major focus for me: how do we develop software that can sustain our organisation now <em>and</em> in the future? How do we structure and organise code so that future change is possible? </p> <p> Whenever I get into debates, that's implicitly the problem on my mind. It'd probably improve communication if I stated this explicitly going into every debate, but sometimes, I get dragged sideways into a debacle... I do, however, speculate that much disagreement may stem from such implicit assumptions. I bring my biases and implicit problem statements into any discussion. I consider it only human if my interlocutors do the same, but their biases and implicit problem understanding may easily be different than mine. What are they, I wonder? </p> <p> This seems to happen not only in the debate about dynamic versus static types. I get a similar sense when I discuss collaboration. Most of my heroes seem to advocate for high-band face-to-face collaboration, while <a href="/2020/03/16/conways-law-latency-versus-throughput">I favour asynchronous, written communication</a>. Indeed, I admit that my bias is speaking. I self-identify as a contrarian introvert (although, again, we should be careful not turning introversion versus extroversion into binary classification). </p> <p> Still, even when I try to account for my bias, I get the sense that my opponents and I may actually try to accomplish a common goal, but by addressing two contrasting problems. </p> <p> <img src="/content/binary/same-goal-different-starting-points.png" alt="Two arrows pointing to the same problem from different directions."> </p> <p> I think and hope that, ultimately, we're trying to accomplish the same goal: to deliver and sustain business capability. </p> <p> I do get the sense that the proponents of more team co-location, more face-to-face collaboration are coming at the problem from a different direction than I am. Perhaps the problem they're trying to solve is micro-management, red tape, overly bureaucratic processes, and a lack of developer autonomy. I can certainly see that if that's the problem, talking to each other is likely to improve the situation. I'd recommend that too, in such a situation. </p> <p> Perhaps it's a local Danish (or perhaps Northern European) phenomenon, but that's not the kind of problem I normally encounter. Most organisations who ask for my help essentially have <em>no</em> process. Everything is ad hoc, nothing is written down, deployment is a manual process, and there are meetings and interruptions all the time. Since nothing is written down, decisions aren't recorded, so team members and stakeholders keep having the same meetings over and over. Again, little gets done, but for an entirely different reason than too much bureaucracy. I see this more frequently than too much red tape, so I tend to recommend that people start leaving behind some sort of written trail of what they've been doing. Pull request reviews, for example, are great for that, and I see <a href="/2021/06/21/agile-pull-requests">no incongruity between agile and pull requests</a>. </p> <h3 id="37232ffbc5cf48e58ec773ca83046807"> Shaped by scars <a href="#37232ffbc5cf48e58ec773ca83046807" title="permalink">#</a> </h3> <p> The inimitable <a href="https://twitter.com/richcampbell">Richard Campbell</a> has phrased our biases as the scars we collect during our careers. If you've deleted the production database one too many times, you develop routines and practices to avoid doing that in the future. If you've mostly worked in an organisation that stifled progress by subjecting you to <a href="https://en.wikipedia.org/wiki/Brazil_(1985_film)">Brazil</a>-levels of bureaucracy, it's understandable if you develop a preference for less formal methods. And if, like me, you've mostly seen dysfunction manifest as a <em>lack</em> of beneficial practices, you develop a taste for written over oral communication. </p> <p> Does it go further than that? Are we also shaped by our successes, just like we are shaped by our scars? </p> <p> The first time I had professional success <em>with a methodology</em> was when I discovered TDD. This made me a true believer in TDD. I'm still a big proponent of TDD, but since I learned what <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">algebraic data types</a> <a href="/2016/11/28/easy-domain-modelling-with-types">can do</a> in terms of modelling, I see <a href="/2011/04/29/Feedbackmechanismsandtradeoffs">no reason to write a run-time test if I instead can get the compiler to enforce a rule</a>. </p> <p> In a recent discussion, some of my heroes expressed the opinion that they don't need <a href="/2021/06/07/abstruse-nomenclature">fancy</a> functional-programming concepts and features to write good code. I'm sure that they don't. </p> <p> My heroes have written code for decades. While I <em>have</em> met bad programmers with decades of experience, most programmers who last that long ultimately become good programmers. I'm not so worried about them. </p> <p> The people who need my help are typically younger teams. Statistically, there just aren't that many <a href="/2020/09/14/we-need-young-programmers-we-need-old-programmers">older programmers</a> around. </p> <p> When I recommend certain practices or programming techniques, those recommendations are aimed at anyone who care to listen. Usually, I find that the audience who engage with me is predominantly programmers with five to ten years of professional experience. </p> <h3 id="0d6d6bee68644d158deb5fa8cf478be7"> Anecdotal evidence <a href="#0d6d6bee68644d158deb5fa8cf478be7" title="permalink">#</a> </h3> <p> This is a difficult discussion to have. I think that another reason that we keep returning to the same controversies is that we mostly rely on <a href="https://martinfowler.com/bliki/AnecdotalEvidence.html">anecdotal evidence</a>. As we progress through our careers, we observe what works and what doesn't, but it's likely that <a href="https://en.wikipedia.org/wiki/Confirmation_bias">confirmation bias</a> makes us remember the results that we already favour, whereas we conveniently forget about the outcomes that don't fit our preferred narrative. </p> <p> Could we settle these discussions with more science? Alas, <a href="/2020/05/25/wheres-the-science">that's difficult</a>. </p> <p> I can't think of anything better, then, than keep having the same discussions over and over. I try hard to overcome my biases to understand the other side, and now and then, I learn something that I find illuminating. It doesn't seem to be a particularly efficient way to address these difficult questions, but I don't know what else to do. What's the alternative to discussion? To <em>not</em> discuss? To <em>not</em> exchange ideas? </p> <p> That seems worse. </p> <h3 id="ea7ed446c9094c1985f585223fbddb26"> Conclusion <a href="#ea7ed446c9094c1985f585223fbddb26" title="permalink">#</a> </h3> <p> In this essay, I've tried to come to grips with an increasing cognitive incongruity that I'm experiencing. I find myself disagreeing with my heroes on a regular basis, and that makes me uncomfortable. Could it be that I'm erecting an echo chamber for myself? </p> <p> The practices that I follow and endorse work well for me, but could I be stuck in a local maximum? </p> <p> This essay has been difficult to write. I'm not sure that I've managed to convey my doubts and motivations. Should I have named my heroes, only to describe how I disagree with them? Will it be seen as aggressive? </p> <p> I hope not. I'm writing about my heroes with reverence and gratitude for all that they've taught me. I mean no harm. </p> <p> At the same time, I'm struggling with reconciling that they rarely seem to agree with me these days. Perhaps they never did. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="0de8cf1ba14ad74a440eb0b29f2e437b"> <div class="comment-author"><a href="https://news.ycombinator.com/tylerhou">tylerhou</a></div> <div class="comment-content"> <p> Re: type systems. I think you are wrong about being wrong. You *can* create languages with type systems that are strong enough to guarantee that if a program compiles, it "works." Languages like this exist. The most well known is <a href="https://en.wikipedia.org/wiki/Coq">Coq</a>, a programming language/proof-assistant which provides tools for proving that properties of your program hold. So literally, if it compiles, your properties are proven true (assuming the proof assistant does not have bugs). </p> <p> Why doesn't halting problem apply here? The halting problem does not conclude that "all programs cannot be determined to halt [for a given input]." It says something much weaker -- there is no algorithm to determine whether an *arbitrary program* will halt given an arbitrary input. But there are still (large) subsets of programs where there *does* exist such a halting algorithm, and practically, these programs are common. In particular, if a language disallows certain types of recursion (or iteration), you can easily prove that programs written in that language will halt. </p> <p> For example, if you used a subset of C that did not allow recursion, goto, or loops, clearly every program written in that subset would terminate. If you expanded your subset to allow loops with a statically-known iteration bound you would know that any program in that new subset would also terminate. Then, instead of only statically bounded loops, you could choose to allow any loop with a finite bound (e.g. iterating over a finite list), and termination would still be guaranteed. </p> <p> I am not as familiar with Coq, so I will discuss a similar language (<a href="https://www.idris-lang.org/">Idris</a>) that implements "substructual recursion," a generalization of the above intuition. In functional languages, the main barrier to proving termination is unbounded recusion. (In imperative languages, loops are also an issue, but loops are equivalent to recursion.) So <a href="https://docs.idris-lang.org/en/latest/tutorial/theorems.html#totality-checking">Idris provides a language subset</a> that only allows substructural recursion -- i.e. if a function <code>f</code> eventually calls itself, it must only call itself with arguments that are "smaller" than the first call. (E.g. for natural numbers smaller means less than, and for lists smaller means a list with a smaller size.) This property is checked at compile time. Since all function cases must be covered the recursive calls must eventually terminate. </p> <p> In practice, most programs don't need unbounded recursion. Most useful algorithms<sup>[citation needed]</sup> have some bound on the number of iterations needed. To modify any arbitrary algorithm to fit a language like Idris it is simple to introduce another natural number parameter <code>N</code> that always decreases by one on recursive calls. When that parameter reaches zero, the function should return an error. Now it is simple for Idris to prove that any call to that function must terminate within <code>N</code> recursions. On the initial call you can set this number to be the upper bound on your algorithm, and since you know that your algorithm will never need that many iterations you know you will always get an answer (the error is just there to satisfy the totality checker). </p> </div> <div class="comment-date">2021-08-11 05:40 UTC</div> </div> <div class="comment" id="02f4fd84d77c4006adc696457fe407dd"> <div class="comment-author"><a href="https://twitter.com/_rchaves_">_rchaves_</a></div> <div class="comment-content"> <p> Hello there! </p> <p> That is a very nice write up, impeccable choice of words. I could see myself a lot in it, except that at some point I was not in disagreement with the dynamic or static types approach, but that somehow I enjoyed both, and couldn’t reconcile this contradiction until some months ago, so I hope my experience can help you too. </p> <p> Going through a recent experience of moving from a consulting company (the one Martin Fowler works on) with good practices and TDD all the way, strong types and no runtime exceptions (Elm) to a Perl shop with no tests, no pull requests, nothing, I can tell you it felt like a roller coaster. </p> <p> At first I thought everything was wrong, and wanted to change it all, to play the consultant. But I decided not to stress out too much about work, and with time I actually started seeing the beauty in all that too, and the advantages this "move fast and break things" culture brought. Meanwhile, on the side, I was still having fun building Elm apps, learning about Haskell, curious about TLA+, writing tests for everything, etc. I felt conflicted, how is it that one can see beauty in both approaches? Which one do I think is the best? </p> <p> Luckily for me, I was also very interested in data, statistics, causality, etc, and somehow I think that lead me to read all the books by Nassim Taleb (one of my heroes now), but it was finally Kent Back (on top of Nassim's insights) that made it all click in place, from a similar experience at Facebook, with his 3X theory, which I really recommend you to watch if you haven't already: <a href="https://www.youtube.com/watch?v=FlJN6_4yI2A">https://www.youtube.com/watch?v=FlJN6_4yI2A</a>. </p> <p> I realised then that my views were actually not in contradiction at all, it was an obvious case of Consulting 101: "it depends". None of the approaches is the best one alone, they are conditional on the environment you are, the risks you face, what are you trying to achieve. You said "we are shaped by our scars", but I think we can (with a lot of effort) actually take a step back and acknowledge our scars as you did, and be mindful of what environments our experiences are conditional too, to try to see different paths that different people went, so you can experience that too and find other "local maxima". Having the two (or more) local maxima in your toolbelt in a way gets you closer to the global maxima :) </p> <p> I also wrote a blogpost, and happy to talk more about it if you are interested: <a href="https://rchavesferna.medium.com/designed-v-evolutionary-code-d52a54408c8f">https://rchavesferna.medium.com/designed-v-evolutionary-code-d52a54408c8f</a> </p> <p> Good luck on your journey <br /> Cheers! </p> </div> <div class="comment-date">2021-08-11 09:44 UTC</div> </div> <div class="comment" id="51a93388e4fe499e9d953afb494ee43a"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> tylerhou, thank you for writing. Yes, you're correct. I should have more explicitly stated that there's no algorithm to determine whether an arbitrary program in a Turing-complete language halts. This does highlight the importance of explicitly stating assumptions and preconditions, which I failed to fully do here. </p> </div> <div class="comment-date">2021-08-12 7:33 UTC</div> </div> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. The Tennis kata revisited https://blog.ploeh.dk/2021/08/03/the-tennis-kata-revisited 2021-08-03T10:45:00+00:00 Mark Seemann <div id="post"> <p> <em>When you need discriminated unions, but all you have are objects.</em> </p> <p> After I learned that <a href="/2018/06/25/visitor-as-a-sum-type">the Visitor design pattern is isomorphic to sum types</a> (AKA <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/discriminated-unions">discriminated unions</a>), I wanted to try how easy it is to carry out a translation in practice. For that reason, I decided to translate my go-to <a href="https://fsharp.org">F#</a> implementation of the <a href="https://codingdojo.org/kata/Tennis">Tennis kata</a> to C#, using the <a href="https://en.wikipedia.org/wiki/Visitor_pattern">Visitor design pattern</a> everywhere I'd use a discriminated union in F#. </p> <p> The resulting C# code shows that it is, indeed, possible to 'mechanically' translate discriminated unions to the Visitor design pattern. Given that the Visitor pattern requires multiple interfaces and classes to model just a single discriminated union, it's no surprise that the resulting code is much more complex. As a solution to the Tennis kata itself, all this complexity is unwarranted. On the other hand, as an exercise in getting by with the available tools, it's quite illustrative. If all you have