ploeh blog 2022-09-27T06:13:58+00:00 Mark Seemann danish software design https://blog.ploeh.dk Refactoring the TCP State pattern example to pure functions https://blog.ploeh.dk/2022/09/26/refactoring-the-tcp-state-pattern-example-to-pure-functions 2022-09-26T05:50:00+00:00 Mark Seemann <div id="post"> <p> <em>A C# example.</em> </p> <p> This article is one of the examples that I promised in the earlier article <a href="/2022/09/05/the-state-pattern-and-the-state-monad">The State pattern and the State monad</a>. That article examines the relationship between the <a href="https://en.wikipedia.org/wiki/State_pattern">State design pattern</a> and the <a href="/2022/06/20/the-state-monad">State monad</a>. That article is deliberately abstract, so one or more examples are in order. </p> <p> In this article, I show you how to start with the example from <a href="/ref/dp">Design Patterns</a> and refactor it to an immutable solution using <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. </p> <p> The code shown here is <a href="https://github.com/ploeh/TCPStateCSharp">available on GitHub</a>. </p> <h3 id="f70ca28a361241e5a352399f8cf912d7"> TCP connection <a href="#f70ca28a361241e5a352399f8cf912d7" title="permalink">#</a> </h3> <p> The example is a class that handles <a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol">TCP</a> connections. The book's example is in C++, while I'll show my C# interpretation. </p> <p> A TCP connection can be in one of several states, so the <code>TcpConnection</code> class keeps an instance of the polymorphic <code>TcpState</code>, which implements the state and transitions between them. </p> <p> <code>TcpConnection</code> plays the role of the State pattern's <code>Context</code>, and <code>TcpState</code> of the <code>State</code>. </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TcpConnection</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;TcpState&nbsp;State&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">TcpConnection</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State&nbsp;=&nbsp;TcpClosed.Instance; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;ActiveOpen() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State.ActiveOpen(<span style="color:blue;">this</span>); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;PassiveOpen() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State.PassiveOpen(<span style="color:blue;">this</span>); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;More&nbsp;members&nbsp;that&nbsp;delegate&nbsp;to&nbsp;State&nbsp;follows...</span></pre> </p> <p> The <code>TcpConnection</code> class' methods delegate to a corresponding method on <code>TcpState</code>, passing itself an argument. This gives the <code>TcpState</code> implementation an opportunity to change the <code>TcpConnection</code>'s <code>State</code> property, which has an <code>internal</code> setter. </p> <h3 id="ffea200499f94145a0686e2481aebf2c"> State <a href="#ffea200499f94145a0686e2481aebf2c" title="permalink">#</a> </h3> <p> This is the <code>TcpState</code> class: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TcpState</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;<span style="color:blue;">void</span>&nbsp;Transmit(TcpConnection&nbsp;connection,&nbsp;TcpOctetStream&nbsp;stream) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;<span style="color:blue;">void</span>&nbsp;ActiveOpen(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;<span style="color:blue;">void</span>&nbsp;PassiveOpen(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;<span style="color:blue;">void</span>&nbsp;Close(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;<span style="color:blue;">void</span>&nbsp;Synchronize(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;<span style="color:blue;">void</span>&nbsp;Acknowledge(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;<span style="color:blue;">void</span>&nbsp;Send(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> I don't consider this entirely <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a> C# code, but it seems closer to the book's C++ example. (It's been a couple of decades since I wrote C++, so I could be mistaken.) It doesn't matter in practice, but instead of a concrete class with <a href="https://en.wikipedia.org/wiki/NOP_(code)">no-op</a> <code>virtual</code> methods, I would usually define an interface. I'll do that in the next example article. </p> <p> The methods have the same names as the methods on <code>TcpConnection</code>, but the signatures are different. All the <code>TcpState</code> methods take a <code>TcpConnection</code> parameter, whereas the <code>TcpConnection</code> methods take no arguments. </p> <p> While the <code>TcpState</code> methods don't do anything, various classes can inherit from the class and override some or all of them. </p> <h3 id="d68a32e30a314c9ea7f45004482a7d98"> Connection closed <a href="#d68a32e30a314c9ea7f45004482a7d98" title="permalink">#</a> </h3> <p> The book shows implementations of three classes that inherit from <code>TcpState</code>, starting with <code>TcpClosed</code>. Here's my translation to C#: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TcpClosed</span>&nbsp;:&nbsp;TcpState { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;TcpState&nbsp;Instance&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TcpClosed(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">TcpClosed</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &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;">void</span>&nbsp;ActiveOpen(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Send&nbsp;SYN,&nbsp;receive&nbsp;SYN,&nbsp;Ack,&nbsp;etc.</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.State&nbsp;=&nbsp;TcpEstablished.Instance; &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;">void</span>&nbsp;PassiveOpen(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.State&nbsp;=&nbsp;TcpListen.Instance; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This implementation overrides <code>ActiveOpen</code> and <code>PassiveOpen</code>. In both cases, after performing some work, they change <code>connection.State</code>. </p> <blockquote> <p> "<code>TCPState</code> subclasses maintain no local state, so they can be shared, and only one instance of each is required. The unique instance of <code>TCPState</code> subclass is obtained by the static <code>Instance</code> operation. [...] </p> <p> "This make each <code>TCPState</code> subclass a Singleton [...]." </p> <footer><cite><a href="/ref/dp">Design Patterns</a></cite></footer> </blockquote> <p> I've maintained that property of each subclass in my C# code, even though it has no impact on the structure of the State pattern. </p> <h3 id="8e21a702cffe4ef09455a29c2981ab39"> The other subclasses <a href="#8e21a702cffe4ef09455a29c2981ab39" title="permalink">#</a> </h3> <p> The next subclass, <code>TcpEstablished</code>, is cast in the same mould: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TcpEstablished</span>&nbsp;:&nbsp;TcpState { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;TcpState&nbsp;Instance&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TcpEstablished(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">TcpEstablished</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &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;">void</span>&nbsp;Close(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;send&nbsp;FIN,&nbsp;receive&nbsp;ACK&nbsp;of&nbsp;FIN</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.State&nbsp;=&nbsp;TcpListen.Instance; &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;">void</span>&nbsp;Transmit( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TcpConnection&nbsp;connection, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TcpOctetStream&nbsp;stream) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.ProcessOctet(stream); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> As is <code>TcpListen</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TcpListen</span>&nbsp;:&nbsp;TcpState { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;TcpState&nbsp;Instance&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TcpListen(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">TcpListen</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &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;">void</span>&nbsp;Send(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Send&nbsp;SYN,&nbsp;receive&nbsp;SYN,&nbsp;ACK,&nbsp;etc.</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.State&nbsp;=&nbsp;TcpEstablished.Instance; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> I admit that I find these examples a bit anaemic, since there's really no logic going on. None of the overrides change state <em>conditionally</em>, which would be possible and make the examples a little more interesting. If you're interested in an example where this happens, see my article <a href="/2021/05/24/tennis-kata-using-the-state-pattern">Tennis kata using the State pattern</a>. </p> <h3 id="68a957ca3dcd40e9986b078223f0763e"> Refactor to pure functions <a href="#68a957ca3dcd40e9986b078223f0763e" title="permalink">#</a> </h3> <p> There's only one obvious source of impurity in the example: The literal <code>State</code> mutation of <code>TcpConnection</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;TcpState&nbsp;State&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">set</span>;&nbsp;}</pre> </p> <p> While client code can't <code>set</code> the <code>State</code> property, subclasses can, and they do. After all, it's how the State pattern works. </p> <p> It's quite a stretch to claim that if we can only get rid of that property setter then all else will be pure. After all, who knows what all those comments actually imply: </p> <p> <pre><span style="color:green;">//&nbsp;Send&nbsp;SYN,&nbsp;receive&nbsp;SYN,&nbsp;ACK,&nbsp;etc.</span></pre> </p> <p> To be honest, we must imagine that <a href="https://en.wikipedia.org/wiki/Input/output">I/O</a> takes place here. This means that even though it's possible to refactor away from mutating the <code>State</code> property, these implementations are not really going to be pure functions. </p> <p> I could try to imagine what that <code>SYN</code> and <code>ACK</code> would look like, but it would be unfounded and hypothetical. I'm not going to do that here. Instead, that's the reason I'm going to publish a second article with a more realistic and complex example. When it comes to the present example, I'm going to proceed with the unreasonable assumption that the comments hide no nondeterministic behaviour or side effects. </p> <p> As outlined in the <a href="/2022/09/05/the-state-pattern-and-the-state-monad">article that compares the State pattern and the State monad</a>, you can refactor state mutation to a pure function by instead returning the new state. Usually, you'd have to return a tuple, because you'd also need to return the 'original' return value. Here, however, the 'return type' of all methods is <code>void</code>, so this isn't necessary. </p> <p> <code>void</code> is <a href="/2018/01/15/unit-isomorphisms">isomorphic to unit</a>, so strictly speaking you could refactor to a return type like <code>Tuple&lt;Unit, TcpConnection&gt;</code>, but that is isomorphic to <code>TcpConnection</code>. (If you need to understand why that is, try writing two functions: One that converts a <code>Tuple&lt;Unit, TcpConnection&gt;</code> to a <code>TcpConnection</code>, and another that converts a <code>TcpConnection</code> to a <code>Tuple&lt;Unit, TcpConnection&gt;</code>.) </p> <p> There's no reason to make things more complicated than they have to be, so I'm going to use the simplest representation: <code>TcpConnection</code>. Thus, you can get rid of the <code>State</code> mutation by instead returning a new <code>TcpConnection</code> from all methods: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TcpConnection</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;TcpState&nbsp;State&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">TcpConnection</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State&nbsp;=&nbsp;TcpClosed.Instance; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">TcpConnection</span>(TcpState&nbsp;state) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State&nbsp;=&nbsp;state; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;TcpConnection&nbsp;ActiveOpen() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;TcpConnection(State.ActiveOpen(<span style="color:blue;">this</span>)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;TcpConnection&nbsp;PassiveOpen() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;TcpConnection(State.PassiveOpen(<span style="color:blue;">this</span>)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;More&nbsp;members&nbsp;that&nbsp;delegate&nbsp;to&nbsp;State&nbsp;follows...</span></pre> </p> <p> The <code>State</code> property no longer has a setter; there's only a public getter. In order to 'change' the state, code must return a new <code>TcpConnection</code> object with the new state. To facilitate that, you'll need to add a constructor overload that takes the new state as an input. Here I made it <code>private</code>, but making it more accessible is not prohibited. </p> <p> This implies, however, that the <code>TcpState</code> methods <em>also</em> return values instead of mutating state. The base class now looks like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TcpState</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;TcpState&nbsp;Transmit(TcpConnection&nbsp;connection,&nbsp;TcpOctetStream&nbsp;stream) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">this</span>; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;TcpState&nbsp;ActiveOpen(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">this</span>; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;TcpState&nbsp;PassiveOpen(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">this</span>; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;And&nbsp;so&nbsp;on...</span></pre> </p> <p> Again, all the methods previously 'returned' <code>void</code>, so while, according to the State monad, you should strictly speaking return <code>Tuple&lt;Unit, TcpState&gt;</code>, this simplifies to <code>TcpState</code>. </p> <p> Individual subclasses now do their work and return other <code>TcpState</code> implementations. I'm not going to tire you with all the example subclasses, so here's just <code>TcpEstablished</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">TcpEstablished</span>&nbsp;:&nbsp;TcpState { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;TcpState&nbsp;Instance&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TcpEstablished(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">TcpEstablished</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;TcpState&nbsp;Close(TcpConnection&nbsp;connection) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;send&nbsp;FIN,&nbsp;receive&nbsp;ACK&nbsp;of&nbsp;FIN</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;TcpListen.Instance; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;TcpState&nbsp;Transmit( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TcpConnection&nbsp;connection, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TcpOctetStream&nbsp;stream) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TcpConnection&nbsp;newConnection&nbsp;=&nbsp;connection.ProcessOctet(stream); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;newConnection.State; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The trickiest implementation is <code>Transmit</code>, since <code>ProcessOctet</code> returns a <code>TcpConnection</code> while the <code>Transmit</code> method has to return a <code>TcpState</code>. Fortunately, the <code>Transmit</code> method can achieve that goal by returning <code>newConnection.State</code>. It feels a bit roundabout, but highlights a point I made in the <a href="/2022/09/05/the-state-pattern-and-the-state-monad">previous article</a>: The <code>TcpConnection</code> and <code>TcpState</code> classes are isomorphic - or, they would be if we made the <code>TcpConnection</code> constructor overload public. Thus, the <code>TcpConnection</code> class is redundant and might be deleted. </p> <h3 id="a94a0e101f6b49d3b4caea30060ae1e1"> Conclusion <a href="#a94a0e101f6b49d3b4caea30060ae1e1" title="permalink">#</a> </h3> <p> This article shows how to refactor the <em>TCP connection</em> sample code from <a href="/ref/dp">Design Patterns</a> to pure functions. </p> <p> If it feels as though something's missing there's a good reason for that. The example, as given, is degenerate because all methods 'return' <code>void</code>, and we don't really know what the actual implementation code (all that <em>Send SYN, receive SYN, ACK, etc.</em>) looks like. This means that we actually don't have to make use of the State monad, because we can get away with <a href="https://en.wikipedia.org/wiki/Endomorphism">endomorphisms</a>. All methods on <code>TcpConnection</code> are really functions that take <code>TcpConnection</code> as input (the instance itself) and return <code>TcpConnection</code>. If you want to see a more realistic example showcasing that perspective, see my article <a href="/2021/05/31/from-state-tennis-to-endomorphism">From State tennis to endomorphism</a>. </p> <p> Even though the example is degenerate, I wanted to show it because otherwise you might wonder how the book's example code fares when exposed to the State monad. To be clear, because of the nature of the example, the State monad never becomes necessary. Thus, we need a second example. </p> <p> <strong>Next:</strong> Refactoring a saga from the State pattern to the State 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>. When to refactor https://blog.ploeh.dk/2022/09/19/when-to-refactor 2022-09-19T06:36:00+00:00 Mark Seemann <div id="post"> <p> <em>FAQ: How do I convince my manager to let me refactor?</em> </p> <p> This question frequently comes up. Developers want to refactor, but are under the impression that managers or other stakeholders will not let them. </p> <p> Sometimes people ask me how to convince their managers to get permission to refactor. I can't answer that. <a href="/2021/03/22/the-dispassionate-developer">I don't know how to convince other people</a>. That's not my métier. </p> <p> I also believe that professional programmers <a href="/2019/03/18/the-programmer-as-decision-maker">should make their own decisions</a>. You don't ask permission to add three lines to a file, or create a new class. Why do you feel that you have to ask permission to refactor? </p> <h3 id="4af4356cd706457ebf8968e92850b140"> Does refactoring take time? <a href="#4af4356cd706457ebf8968e92850b140" title="permalink">#</a> </h3> <p> In <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> I tell the following story: </p> <blockquote> <p> "I once led an effort to <a href="/ref/ddd">refactor towards deeper insight</a>. My colleague and I had identified that the key to implementing a new feature would require changing a fundamental class in our code base. </p> <p> "While such an insight rarely arrives at an opportune time, we wanted to make the change, and our manager allowed it. </p> <p> "A week later, our code still didn’t compile. </p> <p> "I’d hoped that I could make the change to the class in question and then <a href="/ref/welc">lean on the compiler</a> to identify the call sites that needed modification. The problem was that there was an abundance of compilation errors, and fixing them wasn’t a simple question of search-and-replace. </p> <p> "My manager finally took me aside to let me know that he wasn’t satisfied with the situation. I could only concur. </p> <p> "After a mild dressing down, he allowed me to continue the work, and a few more days of heroic effort saw the work completed. </p> <p> "That’s a failure I don’t intend to repeat." </p> <footer><cite><a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a></cite></footer> </blockquote> <p> There's a couple of points to this story. Yes, I <em>did</em> ask for permission before refactoring. I expected the process to take time, and I felt that making such a choice of prioritisation should involve my manager. While this manager trusted me, I felt a moral obligation to be transparent about the work I was doing. I didn't consider it professional to take a week out of the calendar and work on one thing while the rest of the organisation was expecting me to be working on something else. </p> <p> So I can understand why developers feel that they have to ask permission to refactor. After all, refactoring takes time... Doesn't it? </p> <h3 id="ddb8e36130fe475da5ea914ccf06ae45"> Small steps <a href="#ddb8e36130fe475da5ea914ccf06ae45" title="permalink">#</a> </h3> <p> This may unearth the underlying assumption that prevents developers from refactoring: The notion that refactoring takes time. </p> <p> As I wrote in <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, that was a failure I didn't intend to repeat. I've never again asked permission to refactor, because I've never since allowed myself to be in a situation where refactoring would take significant time. </p> <p> The reason I tell the story in the book is that I use it to motivate using the <a href="https://martinfowler.com/bliki/StranglerFigApplication.html">Strangler pattern</a> at the code level. The book proceeds to show an example of that. </p> <p> Migrating code to a new API by allowing the old and the new to coexist for a while is only one of many techniques for taking smaller steps. Another is the use of <a href="https://en.wikipedia.org/wiki/Feature_toggle">feature flags</a>, a technique that I also show in the book. <a href="https://martinfowler.com/">Martin Fowler</a>'s <a href="/ref/refactoring">Refactoring</a> is literally an entire book about how to improve code bases in small, controlled steps. </p> <p> Follow the <a href="/2019/10/21/a-red-green-refactor-checklist">red-green-refactor checklist</a> and commit after each <em>green</em> and <em>refactor</em> step. Move in small steps and <a href="https://stackoverflow.blog/2022/04/06/use-git-tactically/">use Git tactically</a>. </p> <p> I'm beginning to realise, though, that <em>moving in small steps</em> is a skill that must be explicitly learned. This may seem obvious once posited, but it may also be helpful to explicitly state it. </p> <p> Whenever I've had a chance to talk to other software professionals and <a href="https://twitter.com/hillelogram/status/1445435617047990273">thought leaders</a>, they agree. As far as I can tell, universities and coding boot camps don't teach this skill, and if (like me) you're autodidact, you probably haven't learned it either. After all, few people insist that this is an important skill. It may, however, be one of the most important programming skills you can learn. </p> <h3 id="11afa6718a3c4a6f8e50aa5066474ac8"> Make it work, then make it right <a href="#11afa6718a3c4a6f8e50aa5066474ac8" title="permalink">#</a> </h3> <p> When should you refactor? As <a href="https://wiki.c2.com/?BoyScoutRule">the boy scout rule</a> suggests: All the time. </p> <p> You can, specifically, do it after implementing a new feature. As <a href="https://wiki.c2.com/?MakeItWorkMakeItRightMakeItFast">Kent Beck perhaps said or wrote</a>: <em>Make it work, then make it right</em>. </p> <p> How long does it take to make it right? </p> <p> Perhaps you think that it takes as much time as it does to make it work. </p> <p> <img src="/content/binary/make-it-work-then-right-50-50.png" alt="A timeline with two sections: 'make it work' and 'make it right'. Each section has the same size."> </p> <p> Perhaps you think that making it right takes even more time. </p> <p> <img src="/content/binary/make-it-work-then-right-20-80.png" alt="A timeline with two sections: 'make it work' and 'make it right'. The 'make it right' section is substantially larger than the 'make it work' section."> </p> <p> If this is how much time making the code right takes, I can understand why you feel that you need to ask your manager. That's what I did, those many years ago. But what if the proportions are more like this? </p> <p> <img src="/content/binary/make-it-work-then-right-80-20.png" alt="A timeline with two sections: 'make it work' and 'make it right'. The 'make it right' section is substantially smaller than the 'make it work' section."> </p> <p> Do you still feel that you need to ask for permission to refactor? </p> <p> Writing code so that the team can keep a sustainable pace is your job. It's not something you should have to ask for permission to do. </p> <blockquote> <p> "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." </p> <footer><cite>Martin Fowler, <a href="/ref/refactoring">Refactoring</a></cite></footer> </blockquote> <p> Making the code right is not always a huge endeavour. It can be, if you've already made a mess of it, but if it's in good condition, keeping it that way doesn't have to take much extra effort. It's part of the ongoing design process that programming is. </p> <p> How do you know what <em>right</em> is? Doesn't this make-it-work-make-it-right mentality lead to <a href="https://wiki.c2.com/?SpeculativeGenerality">speculative generality</a>? </p> <p> No-one expects you to be able to predict the future, so don't try. Making it right means making the code good in the current context. Use good names, remove duplication, get rid of code smells, keep methods small and complexity low. <a href="/2020/04/13/curb-code-rot-with-thresholds">Refactor if you exceed a threshold</a>. </p> <h3 id="1a2eb1f23d70440c84e518babf7dc373"> Make code easy to change <a href="#1a2eb1f23d70440c84e518babf7dc373" title="permalink">#</a> </h3> <p> The purpose of keeping code in a good condition is to make future changes as easy as possible. If you can't predict the future, however, then how do you know how to factor the code? </p> <p> Another <a href="https://en.wikipedia.org/wiki/Kent_Beck">Kent Beck</a> aphorism suggests a tactic: </p> <blockquote> <p> "for each desired change, make the change easy (warning: this may be hard), then make the easy change" </p> <footer><cite><a href="https://twitter.com/KentBeck/status/250733358307500032">Kent Beck</a></cite></footer> </blockquote> <p> In other words, when you know what you need to accomplish, first refactor the code so that it becomes easier to achieve the goal, and only then write the code to do that. </p> <p> <img src="/content/binary/refactor-implement-40-60.png" alt="A timeline with two sections: Refactor and Implement. The Implement section is visibly larger than the Refactor section."> </p> <p> Should you ask permission to refactor in such a case? Only if you sincerely believe that you can complete the entire task significantly faster without first improving the code. How likely is that? If the code base is already a mess, how easy is it to make changes? Not easy, and granted: That will also be true for refactoring. The difference between first refactoring and <em>not</em> refactoring, however, is that if you refactor, you leave the code in a better state. If you don't, you leave it in a worse state. </p> <p> These decisions compound. </p> <p> But what if, as Kent Beck implies, refactoring is hard? Then the situation might look like this: </p> <p> <img src="/content/binary/refactor-implement-80-20.png" alt="A timeline with two sections: Refactor and Implement. The Refactor section is significantly larger than the Implement section."> </p> <p> Should you ask for permission to refactor? I don't think so. While refactoring in this diagram is most of the work, it makes the change easy. Thus, once you're done refactoring, you make the easy change. The total amount of time this takes may turn out to be quicker than if you hadn't refactored (compare this figure to the previous figure: they're to scale). You also leave the code base in a better state so that future changes may be easier. </p> <h3 id="ff4ce77459af4e64a9e3df797fc01d8d"> Conclusion <a href="#ff4ce77459af4e64a9e3df797fc01d8d" title="permalink">#</a> </h3> <p> There are lots of opportunities for refactoring. Every time you see something that could be improved, why not improve it? The fact that you're already looking at a piece of code suggests that it's somehow relevant to your current task. If it takes ten, fifteen minutes to improve it, why not do it? What if it takes an hour? </p> <p> Most people think nothing of spending hours in meetings without asking their managers. If this is true, you can also decide to use a couple of hours improving code. They're likely as well spent as the meeting hours. </p> <p> The key, however, is to be able to perform opportunistic refactoring. You can't do that if you can only move in day-long iterations; if hours, or days, go by when you can't compile, or when most tests fail. </p> <p> On the other hand, if you're able to incrementally improve the code base in one-minute, or fifteen-minute, steps, then you can improve the code base every time an occasion arrives. </p> <p> This is a skill that you need to learn. You're not born with the ability to improve in small steps. You'll have to practice - for example by <a href="/2020/01/13/on-doing-katas">doing katas</a>. One customer of mine told me that they found Kent Beck's <a href="https://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864">TCR</a> a great way to teach that skill. </p> <p> You can refactor in small steps. It's part of software engineering. Usually, you don't need to ask for permission. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="4dc52487bcee4459857d6fb6741dbcad"> <div class="comment-author"><a href="https://danielt1263.medium.com">Daniel Tartaglia</a></div> <div class="comment-content"> <p> I've always had a problem with the notion of "red, green, refactor" and "first get it working, then make it right." I think the order is completely wrong. </p> <p> As an explanation, I refer you to the first chapter of the first edition of Martin Fowler's Refactoring book. In that chapter is an example of a working system and we are presented with a change request. </p> <p> In the example, the first thing that Fowler points out and does is the refactoring. And one of the highlighted ideas in the chapter says: <blockquote>When you find you have to add a feature to a program, and the program's code is not structured in a convenient way to add the feature, first refactor the program to make it easy to add the feature, then add the feature.</blockquote> </p> <p> In other words, the refactoring <i>comes first</i>. You refactor as part of adding the feature, not as a separate thing that is done after you have working code. It may not trip off the tongue as nicely, but the saying should be "refactor, red, green." </p> <p> Once you have working code, you are done, and when you are estimating the time it will take to add the feature, <i>you include the refactoring time</i>. Lastly, you never refactor "just because," you refactor in order to make a new feature easy to add. </p> <p> This mode of working makes much more sense to me. I feel that refactoring with no clear goal in mind ("improve the design" is not a clear goal) just leads to an over-designed/unnecessarily complex system. What do you think of this idea? </p> </div> <div class="comment-date">2022-09-24 02:28 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>. Coalescing DTOs https://blog.ploeh.dk/2022/09/12/coalescing-dtos 2022-09-12T07:35:00+00:00 Mark Seemann <div id="post"> <p> <em>Refactoring to a universal abstraction.</em> </p> <p> Despite my best efforts, no code base I write is perfect. This is also true for the code base that accompanies <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. </p> <p> One (among several) warts that has annoyed me for long is this: </p> <p> <pre>[HttpPost(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/reservations&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&lt;ActionResult&gt;&nbsp;Post( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;restaurantId, &nbsp;&nbsp;&nbsp;&nbsp;ReservationDto&nbsp;dto) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(dto&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:blue;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(dto)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;id&nbsp;=&nbsp;dto.ParseId()&nbsp;??&nbsp;Guid.NewGuid(); &nbsp;&nbsp;&nbsp;&nbsp;Reservation?&nbsp;reservation&nbsp;=&nbsp;dto.Validate(id); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">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:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;BadRequestResult(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;More&nbsp;code&nbsp;follows...</span></pre> </p> <p> Passing <code>id</code> to <code>Validate</code> annoys me. Why does <code>Validate</code> need an <code>id</code>? </p> <p> When you see it in context, it <em>may</em> makes some sort of sense, but in isolation, it seems arbitrary: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;Reservation?&nbsp;Validate(Guid&nbsp;id)</pre> </p> <p> Why does the method need an <code>id</code>? Doesn't <code>ReservationDto</code> have an <code>Id</code>? </p> <h3 id="90765fa49a8149d0bf54d8d9de19ffee"> Abstraction, broken <a href="#90765fa49a8149d0bf54d8d9de19ffee" title="permalink">#</a> </h3> <p> Yes, indeed, <code>ReservationDto</code> <em>has</em> an <code>Id</code> property: </p> <p> <pre><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> Then why do callers have to pass an <code>id</code> argument? Doesn't <code>Validate</code> use the <code>Id</code> property? It's almost as though the <code>Validate</code> method <em>begs</em> you to read the implementing code: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;Reservation?&nbsp;Validate(Guid&nbsp;id) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(!DateTime.TryParse(At,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;d)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(Email&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:blue;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(Quantity&nbsp;&lt;&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d, &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); }</pre> </p> <p> Indeed, the method doesn't use the <code>Id</code> property. Reading the code may not be of much help, but at least we learn that <code>id</code> is passed to the <code>Reservation</code> constructor. It's still not clear why the method isn't trying to parse the <code>Id</code> property, like it's doing with <code>At</code>. </p> <p> I'll return to the motivation in a moment, but first I'd like to dwell on the problems of this design. </p> <p> It's a typical example of ad-hoc design. I had a set of behaviours I needed to implement, and in order to avoid code duplication, I came up with a method that seemed to solve the problem. </p> <p> And indeed, the <code>Validate</code> method does solve the problem of code duplication. It also passes all tests. It could be worse. </p> <p> It could also be better. </p> <p> The problem with an ad-hoc design like this is that the motivation is unclear. As a reader, you feel that you're missing the full picture. Perhaps you feel compelled to read the implementation code to gain a better understanding. Perhaps you look for other call sites. Perhaps you search the Git history to find a helpful comment. Perhaps you ask a colleague. </p> <p> It slows you down. Worst of all, it may leave you apprehensive of refactoring. If you feel that there's something you don't fully understand, you may decide to leave the API alone, instead of improving it. </p> <p> It's one of the many ways that code slowly rots. </p> <p> What's missing here is a proper abstraction. </p> <h3 id="c6b50930baf541eb9243611e2090b1e6"> Motivation <a href="#c6b50930baf541eb9243611e2090b1e6" title="permalink">#</a> </h3> <p> I recently hit upon a design that I like better. Before I describe it, however, you need to understand the problem I was trying to solve. </p> <p> The code base for the book is a restaurant reservation REST API, and I was evolving the code as I wrote it. I wanted the code base (and its Git history) to be as realistic as possible. In a real-world situation, you don't always know all requirements up front, or even if you do, they may change. </p> <p> At one point I decided that a REST client could supply a <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">GUID</a> when making a new reservation. On the other hand, I had lots of existing tests (and a deployed system) that accepted reservations <em>without</em> IDs. In order to not break compatibility, I decided to use the ID if it was supplied with the <a href="https://en.wikipedia.org/wiki/Data_transfer_object">DTO</a>, and otherwise create one. (I later explored <a href="/2021/09/20/keep-ids-internal-with-rest">an API without explicit IDs</a>, but that's a different story.) </p> <p> The <code>id</code> is a JSON property, however, so there's no guarantee that it's properly formatted. Thus, the need to first parse it: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;id&nbsp;=&nbsp;dto.ParseId()&nbsp;??&nbsp;Guid.NewGuid();</pre> </p> <p> To make matters even more complicated, when you <code>PUT</code> a reservation, the ID is actually part of the resource address, which means that even if it's present in the JSON document, that value should be ignored: </p> <p> <pre>[HttpPut(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/reservations/{id}&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&lt;ActionResult&gt;&nbsp;Put( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;restaurantId, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;id, &nbsp;&nbsp;&nbsp;&nbsp;ReservationDto&nbsp;dto) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(dto&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:blue;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(dto)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(!Guid.TryParse(id,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;rid)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;NotFoundResult(); &nbsp;&nbsp;&nbsp;&nbsp;Reservation?&nbsp;reservation&nbsp;=&nbsp;dto.Validate(rid); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">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:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;BadRequestResult(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;More&nbsp;code&nbsp;follows...</span></pre> </p> <p> Notice that this <code>Put</code> implementation exclusively considers the resource address <code>id</code> parameter. Recall that the <code>Validate</code> method ignores the <code>dto</code>'s <code>Id</code> property. </p> <p> This is knowledge about implementation details that leaks through to the calling code. As a client developer, you need to know and keep this knowledge in your head while you write your own code. That's not really code that fits in your head. </p> <p> As I usually put it: If you have to read the code, it implies that encapsulation is broken. </p> <p> At the time, however, I couldn't think of a better alternative, and since the problem is still fairly small and localised, I decided to move on. After all, <a href="https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good">perfect is the enemy of good</a>. </p> <h3 id="7e10ecc024e94a20817f0054bde56c29"> Why don't you just..? <a href="#7e10ecc024e94a20817f0054bde56c29" title="permalink">#</a> </h3> <p> Is there a better way? Perhaps you think that you've spotted an obvious improvement. Why don't I just try to parse <code>dto.Id</code> and then create a <code>Guid.NewGuid()</code> if parsing fails? Like this: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;Reservation?&nbsp;<span style="color:#74531f;">Validate</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!Guid.TryParse(Id,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">id</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;=&nbsp;Guid.NewGuid(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!DateTime.TryParse(At,&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;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Email&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;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Quantity&nbsp;&lt;&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d, &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); }</pre> </p> <p> The short answer is: Because it doesn't work. </p> <p> It may work for <code>Get</code>, but then <code>Put</code> doesn't have a way to tell the <code>Validate</code> method which ID to use. </p> <p> Or rather: That's not entirely true, because this is possible: </p> <p> <pre>dto.Id&nbsp;=&nbsp;id; Reservation?&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;=&nbsp;dto.Validate();</pre> </p> <p> This does suggest an even better way. Before we go there, however, there's another reason I don't like this particular variation: It makes <code>Validate</code> impure. </p> <p> <em>Why care?</em> you may ask. </p> <p> I always end up regretting making an otherwise potentially <a href="https://en.wikipedia.org/wiki/Pure_function">pure function</a> non-deterministic. Sooner or later, it turns out to have been a bad decision, regardless of how alluring it initially looked. <a href="/2022/05/23/waiting-to-never-happen">I recently gave an example of that</a>. </p> <p> When weighing the advantages and disadvantages, I preferred passing <code>id</code> explicitly rather than relying on <code>Guid.NewGuid()</code> inside <code>Validate</code>. </p> <h3 id="cb79dc6987854f8b9a897285af649360"> First monoid <a href="#cb79dc6987854f8b9a897285af649360" title="permalink">#</a> </h3> <p> One of the reasons I find <a href="/2017/10/04/from-design-patterns-to-category-theory">universal abstractions</a> beneficial is that you only have to learn them once. As Felienne Hermans writes in <a href="/ref/programmers-brain">The Programmer's Brain</a> our working memory juggles a combination of ephemeral data and knowledge from our long-term memory. The better you can leverage existing knowledge, the easier it is to read code. </p> <p> Which universal abstraction enables you to choose from a prioritised list of candidates? The <a href="/2018/04/03/maybe-monoids">First monoid</a>! </p> <p> In C# with <a href="https://docs.microsoft.com/dotnet/csharp/nullable-references">nullable reference types</a> the <a href="https://docs.microsoft.com/dotnet/csharp/language-reference/operators/null-coalescing-operator">null-coalescing operator</a> <code>??</code> already implements the desired functionality. (If you're using another language or an older version of C#, you can instead use <a href="/2018/06/04/church-encoded-maybe">Maybe</a>.) </p> <p> Once I got that idea I was able to simplify the API. </p> <h3 id="ad2f0a4d20da4c9c8006e9587b011911"> Parsing and coalescing DTOs <a href="#ad2f0a4d20da4c9c8006e9587b011911" title="permalink">#</a> </h3> <p> Instead of that odd <code>Validate</code> method which isn't quite a validator and not quite a parser, this insight suggests to <a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/">parse, don't validate</a>: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;Reservation?&nbsp;<span style="color:#74531f;">TryParse</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!Guid.TryParse(Id,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">id</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!DateTime.TryParse(At,&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;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Email&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;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Quantity&nbsp;&lt;&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d, &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); }</pre> </p> <p> This function only returns a parsed <code>Reservation</code> object when the <code>Id</code> is present and well-formed. What about the cases where the <code>Id</code> is absent? </p> <p> The calling <code>ReservationsController</code> can deal with that: </p> <p> <pre>Reservation?&nbsp;<span style="color:#1f377f;">candidate1</span>&nbsp;=&nbsp;dto.TryParse(); dto.Id&nbsp;=&nbsp;Guid.NewGuid().ToString(<span style="color:#a31515;">&quot;N&quot;</span>); Reservation?&nbsp;<span style="color:#1f377f;">candidate2</span>&nbsp;=&nbsp;dto.TryParse(); Reservation?&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;=&nbsp;candidate1&nbsp;??&nbsp;candidate2; <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;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;BadRequestResult();</pre> </p> <p> First try to parse the <code>dto</code>, then explicitly overwrite its <code>Id</code> property with a new <code>Guid</code>, and then try to parse it again. Finally, pick the first of these that aren't null, using the null-coalescing <code>??</code> operator. </p> <p> This API also works consistently in the <code>Put</code> method: </p> <p> <pre>dto.Id&nbsp;=&nbsp;id; Reservation?&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;=&nbsp;dto.TryParse(); <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;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;BadRequestResult();</pre> </p> <p> Why is this better? I consider it better because the <code>TryParse</code> function should be a familiar abstraction. Once you've seen a couple of those, you know that a well-behaved parser either returns a valid object, or nothing. You don't have to go and read the implementation of <code>TryParse</code> to (correctly) guess that. Thus, encapsulation is maintained. </p> <h3 id="72d1eececc3f4166ba426d6a39cd6721"> Where does mutation go? <a href="#72d1eececc3f4166ba426d6a39cd6721" title="permalink">#</a> </h3> <p> The <code>ReservationsController</code> mutates the <code>dto</code> and relies on the impure <code>Guid.NewGuid()</code> method. Why is that okay when it wasn't okay to do this inside of <code>Validate</code>? </p> <p> This is because the code base follows the <a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">functional core, imperative shell</a> architecture. Specifically, Controllers make up the imperative shell, so I consider it appropriate to put impure actions there. After all, they have to go somewhere. </p> <p> This means that the <code>TryParse</code> function remains pure. </p> <h3 id="85ce3840fad04a0c8cb106f6d36459d5"> Conclusion <a href="#85ce3840fad04a0c8cb106f6d36459d5" title="permalink">#</a> </h3> <p> Sometimes a good API design can elude you for a long time. When that happens, I move on with the best solution I can think of in the moment. As it often happens, though, ad-hoc abstractions leave me unsatisfied, so I'm always happy to improve such code later, if possible. </p> <p> In this article, you saw an example of an ad-hoc API design that represented the best I could produce at the time. Later, it dawned on me that an implementation based on a universal abstraction would be possible. In this case, the universal abstraction was null coalescing (which is a specialisation of the <em>monoid</em> abstraction). </p> <p> I like universal abstractions because, once you know them, you can trust that they work in well-understood ways. You don't have to waste time reading implementation code in order to learn whether it's safe to call a method in a particular way. </p> <p> This saves time when you have to work with the code, because, after all, we spend more time reading code than writing it. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="abb3e1c91878423a94835a798fc8b32d"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <p> After the refactor in this article, is the entirety of your Post method (including the part you didn't show in this article) an <a href="https://blog.ploeh.dk/2020/03/02/impureim-sandwich/">impureim sandwich</a>? </p> </div> <div class="comment-date">2022-09-17 18:37 UTC</div> </div> <div class="comment" id="2352255931b1499184b5ba3782436d61"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Not yet. There's a lot of (preliminary) interleaving of impure actions and pure functions remaining in the controller, even after this refactoring. </p> <p> A future article will tackle that question. One of the reasons I even started writing about monads, functor relationships, etcetera was to establish the foundations for what this requires. If it can be done without monads and traversals I don't know how. </p> <p> Even though the <code>Post</code> method isn't an impureim sandwich, I still consider the architecture <a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">functional core, imperative shell</a>, since I've kept all impure actions in the controllers. </p> <p> The reason I didn't go all the way to impureim sandwiches with the book's code is didactic. For complex logic, you'll need traversals, monads, sum types, and so on, and none of those things were in scope for the book. </p> </div> <div class="comment-date">2022-09-18 19:28 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 State pattern and the State monad https://blog.ploeh.dk/2022/09/05/the-state-pattern-and-the-state-monad 2022-09-05T12:48:00+00:00 Mark Seemann <div id="post"> <p> <em>The names are the same. Is there a connection? An article for object-oriented programmers.</em> </p> <p> This article is part of <a href="/2018/03/05/some-design-patterns-as-universal-abstractions">a series of articles about specific design patterns and their category theory counterparts</a>. In this article I compare the <a href="https://en.wikipedia.org/wiki/State_pattern">State design pattern</a> to the <a href="/2022/06/20/the-state-monad">State monad</a>. </p> <p> Since the design pattern and the monad share the name <em>State</em> you'd think that they might be <a href="/2018/01/08/software-design-isomorphisms">isomorphic</a>, but it's not quite that easy. I find it more likely that the name is an example of <a href="https://en.wikipedia.org/wiki/Parallel_evolution">parallel evolution</a>. Monads were discovered by <a href="https://en.wikipedia.org/wiki/Eugenio_Moggi">Eugenio Moggi</a> in the early nineties, and <a href="/ref/dp">Design Patterns</a> is from 1994. That's close enough in time that I find it more likely that whoever came up with the names found them independently. <em>State</em>, after all, is hardly an exotic word. </p> <p> Thus, it's possible that the choice of the same name is coincidental. If this is true (which is only my conjecture), does the State pattern have anything in common with the State monad? I find that the answer is a tentative <em>yes</em>. The State design pattern describes an open polymorphic stateful computation. That kind of computation can also be described with the State monad. </p> <p> This article contains a significant amount of code, and it's all quite abstract. It examines the abstract shape of the pattern, so there's little prior intuition on which to build an understanding. While later articles will show more concrete examples, if you want to follow along, you can use the <a href="https://github.com/ploeh/StatePatternAndMonad">GitHub repository</a>. </p> <h3 id="320763be103b49018debc64b45069e3c"> Shape <a href="#320763be103b49018debc64b45069e3c" title="permalink">#</a> </h3> <p> <a href="/ref/dp">Design Patterns</a> is a little vague when it comes to representing the essential form of the pattern. What one can deduce from the diagram in the <em>Structure</em> section describing the pattern, you have an abstract <code>State</code> class with a <code>Handle</code> method like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">virtual</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Handle</span>(Context&nbsp;<span style="color:#1f377f;">context</span>) { }</pre> </p> <p> This, however, doesn't capture all scenarios. What if you need to pass more arguments to the method? What if the method returns a result? What if there's more than one method? </p> <p> Taking into account all those concerns, you might arrive at a more generalised description of the State pattern where an abstract <code>State</code> class might define methods like these: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;Out1&nbsp;<span style="color:#74531f;">Handle1</span>(Context&nbsp;<span style="color:#1f377f;">context</span>,&nbsp;In1&nbsp;<span style="color:#1f377f;">in1</span>); <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;Out2&nbsp;<span style="color:#74531f;">Handle2</span>(Context&nbsp;<span style="color:#1f377f;">context</span>,&nbsp;In2&nbsp;<span style="color:#1f377f;">in2</span>);</pre> </p> <p> There might be an arbitrary number of <code>Handle</code> methods, from <code>Handle1</code> to <code>HandleN</code>, each with their own input and return types. </p> <p> The idea behind the State pattern is that clients don't interact directly with <code>State</code> objects. Instead, they interact with a <code>Context</code> object that delegates operations to a <code>State</code> object, passing itself as an argument: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Out1&nbsp;<span style="color:#74531f;">Request1</span>(In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;State.Handle1(<span style="color:blue;">this</span>,&nbsp;in1); } <span style="color:blue;">public</span>&nbsp;Out2&nbsp;<span style="color:#74531f;">Request2</span>(In2&nbsp;<span style="color:#1f377f;">in2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;State.Handle2(<span style="color:blue;">this</span>,&nbsp;in2); }</pre> </p> <p> Classes that derive from the abstract <code>State</code> may then mutate <code>context.State</code>. </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;Out2&nbsp;<span style="color:#74531f;">Handle2</span>(Context&nbsp;<span style="color:#1f377f;">context</span>,&nbsp;In2&nbsp;<span style="color:#1f377f;">in2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(in2&nbsp;==&nbsp;In2.Epsilon) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.State&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;ConcreteStateB(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Out2.Eta; }</pre> </p> <p> Clients interact with the <code>Context</code> object and aren't aware of this internal machinery: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;ctx.Request2(in2);</pre> </p> <p> With such state mutation going on, is it possible to refactor to a design that uses immutable data and <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>? </p> <h3 id="463f29ae1f8240ec8de7ed18cd429b9f"> State pair <a href="#463f29ae1f8240ec8de7ed18cd429b9f" title="permalink">#</a> </h3> <p> When you have a <code>void</code> method that mutates state, you can refactor it to a pure function by leaving the existing state unchanged and instead returning the new state. What do you do, however, when the method in question already returns a value? </p> <p> This is the case with the generalised <code>HandleN</code> methods, above. </p> <p> One way to resolve this problem is to introduce a more complex type to return. To avoid too much duplication or boilerplate code, you could make it a generic type: </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;">StatePair</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">StatePair</span>(T&nbsp;<span style="color:#1f377f;">value</span>,&nbsp;State&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;=&nbsp;value; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State&nbsp;=&nbsp;state; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;Value&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;State&nbsp;State&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;StatePair&lt;T&gt;&nbsp;<span style="color:#1f377f;">result</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;T&gt;.Default.Equals(Value,&nbsp;result.Value)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;State&gt;.Default.Equals(State,&nbsp;result.State); &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(Value,&nbsp;State); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This enables you to change the signatures of the <code>Handle</code> methods: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;StatePair&lt;Out1&gt;&nbsp;<span style="color:#74531f;">Handle1</span>(Context&nbsp;<span style="color:#1f377f;">context</span>,&nbsp;In1&nbsp;<span style="color:#1f377f;">in1</span>); <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;StatePair&lt;Out2&gt;&nbsp;<span style="color:#74531f;">Handle2</span>(Context&nbsp;<span style="color:#1f377f;">context</span>,&nbsp;In2&nbsp;<span style="color:#1f377f;">in2</span>);</pre> </p> <p> This refactoring is always possible. Even if the original return type of a method was <code>void</code>, you can <a href="/2018/01/15/unit-isomorphisms">use a <em>unit</em> type as a replacement for <em>void</em></a>. While redundant but consistent, a method could return <code>StatePair&lt;Unit&gt;</code>. </p> <h3 id="e2ca8d320e684cf89407880d06256b64"> Generic pair <a href="#e2ca8d320e684cf89407880d06256b64" title="permalink">#</a> </h3> <p> The above <code>StatePair</code> type is so coupled to a particular <code>State</code> class that it's not reusable. If you had more than one implementation of the State pattern in your code base, you'd have to duplicate that effort. That seems wasteful, so why not make the type generic in the state dimension as well? </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;">StatePair</span>&lt;<span style="color:#2b91af;">TState</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">StatePair</span>(T&nbsp;<span style="color:#1f377f;">value</span>,&nbsp;TState&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;=&nbsp;value; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State&nbsp;=&nbsp;state; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;Value&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;TState&nbsp;State&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;StatePair&lt;TState,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">pair</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;T&gt;.Default.Equals(Value,&nbsp;pair.Value)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;TState&gt;.Default.Equals(State,&nbsp;pair.State); &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(Value,&nbsp;State); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> When you do that then clearly you'd also need to modify the <code>Handle</code> methods accordingly: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;StatePair&lt;State,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Handle1</span>(Context&nbsp;<span style="color:#1f377f;">context</span>,&nbsp;In1&nbsp;<span style="color:#1f377f;">in1</span>); <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;StatePair&lt;State,&nbsp;Out2&gt;&nbsp;<span style="color:#74531f;">Handle2</span>(Context&nbsp;<span style="color:#1f377f;">context</span>,&nbsp;In2&nbsp;<span style="color:#1f377f;">in2</span>);</pre> </p> <p> Notice that, as is the case with <a href="/2021/07/19/the-state-functor">the State functor</a>, the <em>type</em> declares the type with <code>TState</code> before <code>T</code>, while the <em>constructor</em> takes <code>T</code> before <code>TState</code>. While odd and potentially confusing, I've done this to stay consistent with my previous articles, which again do this to stay consistent with prior art (mainly <a href="https://www.haskell.org/">Haskell</a>). </p> <p> With <code>StatePair</code> you can make the methods pure. </p> <h3 id="cacad33b630d4529b4f703337b9b0a61"> Pure functions <a href="#cacad33b630d4529b4f703337b9b0a61" title="permalink">#</a> </h3> <p> Since <code>Handle</code> methods can now return a new state instead of mutating objects, they can be pure functions. Here's an example: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;StatePair&lt;State,&nbsp;Out2&gt;&nbsp;<span style="color:#74531f;">Handle2</span>(Context&nbsp;<span style="color:#1f377f;">context</span>,&nbsp;In2&nbsp;<span style="color:#1f377f;">in2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(in2&nbsp;==&nbsp;In2.Epsilon) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;StatePair&lt;State,&nbsp;Out2&gt;(Out2.Eta,&nbsp;<span style="color:blue;">new</span>&nbsp;ConcreteStateB()); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;StatePair&lt;State,&nbsp;Out2&gt;(Out2.Eta,&nbsp;<span style="color:blue;">this</span>); }</pre> </p> <p> The same is true for <code>Context</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;StatePair&lt;Context,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Request1</span>(In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">pair</span>&nbsp;=&nbsp;State.Handle1(<span style="color:blue;">this</span>,&nbsp;in1); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;StatePair&lt;Context,&nbsp;Out1&gt;(pair.Value,&nbsp;<span style="color:blue;">new</span>&nbsp;Context(pair.State)); } <span style="color:blue;">public</span>&nbsp;StatePair&lt;Context,&nbsp;Out2&gt;&nbsp;<span style="color:#74531f;">Request2</span>(In2&nbsp;<span style="color:#1f377f;">in2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">pair</span>&nbsp;=&nbsp;State.Handle2(<span style="color:blue;">this</span>,&nbsp;in2); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;StatePair&lt;Context,&nbsp;Out2&gt;(pair.Value,&nbsp;<span style="color:blue;">new</span>&nbsp;Context(pair.State)); }</pre> </p> <p> Does this begin to look familiar? </p> <h3 id="bf25630a0d324f628f400c73ddaa78fa"> Monad <a href="#bf25630a0d324f628f400c73ddaa78fa" title="permalink">#</a> </h3> <p> The <code>StatePair</code> class is nothing but a glorified tuple. Armed with that knowledge, you can introduce a variation of <a href="/2021/07/19/the-state-functor">the IState interface I used to introduce the State functor</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IState</span>&lt;<span style="color:#2b91af;">TState</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;StatePair&lt;TState,&nbsp;T&gt;&nbsp;<span style="color:#74531f;">Run</span>(TState&nbsp;<span style="color:#1f377f;">state</span>); }</pre> </p> <p> This variation uses the explicit <code>StatePair</code> class as the return type of <code>Run</code>, rather than a more anonymous tuple. These representations are isomorphic. (That might be a good exercise: Write functions that convert from one to the other, and vice versa.) </p> <p> You can write the usual <code>Select</code> and <code>SelectMany</code> implementations to make <code>IState</code> a functor and monad. Since I have already shown these in previous articles, I'm also going to skip those. (Again, it might be a good exercise to implement them if you're in doubt of how they work.) </p> <p> You can now, for example, use C# query syntax to run the same computation multiple times: </p> <p> <pre>IState&lt;Context,&nbsp;(Out1&nbsp;a,&nbsp;Out1&nbsp;b)&gt;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;a&nbsp;<span style="color:blue;">in</span>&nbsp;in1.Request1() &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;b&nbsp;<span style="color:blue;">in</span>&nbsp;in1.Request1() &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;(a,&nbsp;b); StatePair&lt;Context,&nbsp;(Out1&nbsp;a,&nbsp;Out1&nbsp;b)&gt;&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;s.Run(ctx);</pre> </p> <p> This example calls <code>Request1</code> twice, and collects both return values in a tuple. Running the computation with a <code>Context</code> will produce both a result (the two outputs <code>a</code> and <code>b</code>) as well as the 'current' <code>Context</code> (state). </p> <p> <code>Request1</code> is a State-valued extension method on <code>In1</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;Context,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Request1</span>(<span style="color:blue;">this</span>&nbsp;In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;ctx&nbsp;<span style="color:blue;">in</span>&nbsp;Get&lt;Context&gt;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;p&nbsp;=&nbsp;ctx.Request1(in1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;_&nbsp;<span style="color:blue;">in</span>&nbsp;Put(p.State) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;p.Value; }</pre> </p> <p> Notice the abstraction level in play. This extension method doesn't return a <code>StatePair</code>, but rather an <code>IState</code> computation, defined by using <a href="/2022/07/04/get-and-put-state">the State monad's Get and Put functions</a>. Since the computation is running with a <code>Context</code> state, the computation can <code>Get</code> a <code>ctx</code> object and call its <code>Request1</code> method. This method returns a pair <code>p</code>. The computation can then <code>Put</code> the pair's <code>State</code> (here, a <code>Context</code> object) and return the pair's <code>Value</code>. </p> <p> This stateful computation is composed from the building blocks of the State monad, including query syntax supported by <code>SelectMany</code>, <code>Get</code>, and <code>Put</code>. </p> <p> This does, however, still feel unsatisfactory. After all, you have to know enough of the details of the State monad to know that <code>ctx.Request1</code> returns a pair of which you must remember to <code>Put</code> the <code>State</code>. Would it be possible to also express the underlying <code>Handle</code> methods as stateful computations? </p> <h3 id="f8c4147c58924cd19f1d0bdae8fc05a5"> StatePair bifunctor <a href="#f8c4147c58924cd19f1d0bdae8fc05a5" title="permalink">#</a> </h3> <p> The <code>StatePair</code> class is isomorphic to a <em>pair</em> (a <em>two-tuple</em>), and we know that <a href="/2018/12/31/tuple-bifunctor">a pair gives rise to a bifunctor</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;StatePair&lt;TState1,&nbsp;T1&gt;&nbsp;<span style="color:#74531f;">SelectBoth</span>&lt;<span style="color:#2b91af;">TState1</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;T1&gt;&nbsp;<span style="color:#1f377f;">selectValue</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TState,&nbsp;TState1&gt;&nbsp;<span style="color:#1f377f;">selectState</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;StatePair&lt;TState1,&nbsp;T1&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectValue(Value), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectState(State)); }</pre> </p> <p> You can use <code>SelectBoth</code> to implement both <code>Select</code> and <code>SelectState</code>. In the following we're only going to need <code>SelectState</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;StatePair&lt;TState1,&nbsp;T&gt;&nbsp;<span style="color:#74531f;">SelectState</span>&lt;<span style="color:#2b91af;">TState1</span>&gt;(Func&lt;TState,&nbsp;TState1&gt;&nbsp;<span style="color:#1f377f;">selectState</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;SelectBoth(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x,&nbsp;selectState); }</pre> </p> <p> This enables us to slightly simplify the <code>Context</code> methods: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;StatePair&lt;Context,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Request1</span>(In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;State.Handle1(<span style="color:blue;">this</span>,&nbsp;in1).SelectState(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Context(s)); } <span style="color:blue;">public</span>&nbsp;StatePair&lt;Context,&nbsp;Out2&gt;&nbsp;<span style="color:#74531f;">Request2</span>(In2&nbsp;<span style="color:#1f377f;">in2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;State.Handle2(<span style="color:blue;">this</span>,&nbsp;in2).SelectState(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Context(s)); }</pre> </p> <p> Keep in mind that <code>Handle1</code> returns a <code>StatePair&lt;State,&nbsp;Out1&gt;</code>, <code>Handle2</code> returns <code>StatePair&lt;State,&nbsp;Out2&gt;</code>, and so on. While <code>Request1</code> calls <code>Handle1</code>, it must return a <code>StatePair&lt;Context,&nbsp;Out1&gt;</code> rather than a <code>StatePair&lt;State,&nbsp;Out1&gt;</code>. Since <code>StatePair</code> is a bifunctor, the <code>Request1</code> method can use <code>SelectState</code> to map the <code>State</code> to a <code>Context</code>. </p> <p> Unfortunately, this doesn't seem to move us much closer to being able to express the underlying functions as stateful computations. It does, however, set up the code so that the next change is a little easier to follow. </p> <h3 id="21f08903569d4c1a898914092f2bf3f9"> State computations <a href="#21f08903569d4c1a898914092f2bf3f9" title="permalink">#</a> </h3> <p> Is it possible to express the <code>Handle</code> methods on <code>State</code> as <code>IState</code> computations? One option is to write another extension method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;State,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Request1S</span>(<span style="color:blue;">this</span>&nbsp;In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;s&nbsp;<span style="color:blue;">in</span>&nbsp;Get&lt;State&gt;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;ctx&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Context(s) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;p&nbsp;=&nbsp;s.Handle1(ctx,&nbsp;in1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;_&nbsp;<span style="color:blue;">in</span>&nbsp;Put(p.State) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;p.Value; }</pre> </p> <p> I had to add an <code>S</code> suffix to the name, since it only differs from the above <code>Request1</code> extension method on its return type, and C# doesn't allow method overloading on return types. </p> <p> You can add a similar <code>Request2S</code> extension method. It feels like boilerplate code, but enables us to express the <code>Context</code> methods in terms of running stateful computations: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;StatePair&lt;Context,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Request1</span>(In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;in1.Request1S().Run(State).SelectState(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Context(s)); } <span style="color:blue;">public</span>&nbsp;StatePair&lt;Context,&nbsp;Out2&gt;&nbsp;<span style="color:#74531f;">Request2</span>(In2&nbsp;<span style="color:#1f377f;">in2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;in2.Request2S().Run(State).SelectState(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Context(s)); }</pre> </p> <p> This still isn't entirely satisfactory, since the return types of these <code>Request</code> methods are state pairs, and not <code>IState</code> values. The above <code>Request1S</code> function, however, contains a clue about how to proceed. Notice how it can create a <code>Context</code> object from the underlying <code>State</code>, and convert that <code>Context</code> object back to a <code>State</code> object. That's a generalizable idea. </p> <h3 id="6ec1667fe3354e8bb9b5f7b3540b74f9"> Invariant functor <a href="#6ec1667fe3354e8bb9b5f7b3540b74f9" title="permalink">#</a> </h3> <p> While it's possible to map the <code>TState</code> dimension of the state pair, it seems harder to do it on <code><span style="color:#2b91af;">IState</span>&lt;<span style="color:#2b91af;">TState</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt;</code>. A tuple, after all, is covariant in both dimensions. The State monad, on the other hand, is neither co- nor contravariant in the state dimension. You can deduce this with positional variance analysis (which I've learned from <a href="https://thinkingwithtypes.com/">Thinking with Types</a>). In short, this is because <code>TState</code> appears as both input and output in <code>StatePair&lt;TState,&nbsp;T&gt;&nbsp;<span style="color:#74531f;">Run</span>(TState&nbsp;<span style="color:#1f377f;">state</span>)</code> - it's neither co- nor contravariant, but rather <em>invariant</em>. </p> <p> What little option is left us, then, is to make <code>IState</code> an <a href="/2022/08/01/invariant-functors">invariant functor</a> in the state dimension: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;TState1,&nbsp;T&gt;&nbsp;<span style="color:#74531f;">SelectState</span>&lt;<span style="color:#2b91af;">TState</span>,&nbsp;<span style="color:#2b91af;">TState1</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IState&lt;TState,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">state</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TState,&nbsp;TState1&gt;&nbsp;<span style="color:#1f377f;">forward</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TState1,&nbsp;TState&gt;&nbsp;<span style="color:#1f377f;">back</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;s1&nbsp;<span style="color:blue;">in</span>&nbsp;Get&lt;TState1&gt;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;s&nbsp;=&nbsp;back(s1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;p&nbsp;=&nbsp;state.Run(s) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;_&nbsp;<span style="color:blue;">in</span>&nbsp;Put(forward(p.State)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;p.Value; }</pre> </p> <p> Given an <code>IState&lt;TState,&nbsp;T&gt;</code> the <code>SelectState</code> function enables us to turn it into a <code>IState&lt;TState1,&nbsp;T&gt;</code>. This is, however, only possible if you can translate both <code>forward</code> and <code>back</code> between two representations. When we have two such translations, we can produce a new computation that runs in <code>TState1</code> by first using <code>Get</code> to retrieve a <code>TState1</code> value from the new environment, translate it <code>back</code> to <code>TState</code>, which enables the expression to <code>Run</code> the <code>state</code>. Then translate the resulting <code>p.State</code> <code>forward</code> and <code>Put</code> it. Finally, return the <code>Value</code>. </p> <p> As <a href="https://reasonablypolymorphic.com/">Sandy Maguire</a> explains: </p> <blockquote> <p> "... an invariant type <code>T</code> allows you to map from <code>a</code> to <code>b</code> if and only if <code>a</code> and <code>b</code> are isomorphic. [...] an isomorphism between <code>a</code> and <code>b</code> means they're already the same thing to begin with." </p> <footer><cite>Sandy Maguire, <a href="https://thinkingwithtypes.com/">Thinking with Types</a></cite></footer> </blockquote> <p> This may seem limiting, but is enough in this case. The <code>Context</code> class is only a wrapper of a <code>State</code> object: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Context</span>(State&nbsp;<span style="color:#1f377f;">state</span>) { &nbsp;&nbsp;&nbsp;&nbsp;State&nbsp;=&nbsp;state; } <span style="color:blue;">public</span>&nbsp;State&nbsp;State&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;}</pre> </p> <p> If you have a <code>State</code> object, you can create a <code>Context</code> object via the <code>Context</code> constructor. On the other hand, if you have a <code>Context</code> object, you can get the wrapped <code>State</code> object by reading the <code>State</code> property. </p> <p> The first improvement this offers is simplification of the <code>Request1</code> extension method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;Context,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Request1</span>(<span style="color:blue;">this</span>&nbsp;In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;in1.Request1S().SelectState(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;Context(s),&nbsp;<span style="color:#1f377f;">ctx</span>&nbsp;=&gt;&nbsp;ctx.State); }</pre> </p> <p> Recall that <code>Request1S</code> returns a <code>IState&lt;State,&nbsp;Out1&gt;</code>. Since a two-way translation between <code>State</code> and <code>Context</code> exists, <code>SelectState</code> can translate <code>IState&lt;State,&nbsp;Out1&gt;</code> to <code>IState&lt;Context,&nbsp;Out1&gt;</code>. </p> <p> The same applies to the equivalent <code>Request2</code> extension method. </p> <p> This, again, enables us to rewrite the <code>Context</code> methods: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;StatePair&lt;Context,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Request1</span>(In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;in1.Request1().Run(<span style="color:blue;">this</span>); } <span style="color:blue;">public</span>&nbsp;StatePair&lt;Context,&nbsp;Out2&gt;&nbsp;<span style="color:#74531f;">Request2</span>(In2&nbsp;<span style="color:#1f377f;">in2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;in2.Request2().Run(<span style="color:blue;">this</span>); }</pre> </p> <p> While this may seem like an insignificant change, one result has been gained: This last refactoring pushed the <code>Run</code> call to the right. It's now clear that each expression is a stateful computation, and that the only role that the <code>Request</code> methods play is to <code>Run</code> the computations. </p> <p> This illustrates that the <code>Request</code> methods can be decomposed into two decoupled steps: <ol> <li>A stateful computation expression</li> <li>Running the expression</li> </ol> The question now becomes: How useful is the <code>Context</code> wrapper class now? </p> <h3 id="4fc39c9d7bd647cb9773344082468051"> Eliminating the Context <a href="#4fc39c9d7bd647cb9773344082468051" title="permalink">#</a> </h3> <p> A reasonable next refactoring might be to remove the <code>context</code> parameter from each of the <code>Handle</code> methods. After all, this parameter is a remnant of the State design pattern. Its original purpose was to enable <code>State</code> implementers to mutate the <code>context</code> by changing its <code>State</code>. </p> <p> After refactoring to immutable functions, the <code>context</code> parameter no longer needs to be there - for that reason. Do we need it for other reasons? Does it carry other information that a <code>State</code> implementer might need? </p> <p> In the form that the code now has, it doesn't. Even if it did, we could consider moving that data to the other input parameter: <code>In1</code>, <code>In2</code>, etcetera. </p> <p> Therefore, it seems sensible to remove the <code>context</code> parameter from the <code>State</code> methods: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;StatePair&lt;State,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Handle1</span>(In1&nbsp;<span style="color:#1f377f;">in1</span>); <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;StatePair&lt;State,&nbsp;Out2&gt;&nbsp;<span style="color:#74531f;">Handle2</span>(In2&nbsp;<span style="color:#1f377f;">in2</span>);</pre> </p> <p> This also means that a function like <code>Request1S</code> becomes simpler: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;State,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Request1S</span>(<span style="color:blue;">this</span>&nbsp;In1&nbsp;<span style="color:#1f377f;">in1</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;s&nbsp;<span style="color:blue;">in</span>&nbsp;Get&lt;State&gt;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;p&nbsp;=&nbsp;s.Handle1(in1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;_&nbsp;<span style="color:blue;">in</span>&nbsp;Put(p.State) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;p.Value; }</pre> </p> <p> Since <code>Context</code> and <code>State</code> are isomorphic, you can rewrite all callers of <code>Context</code> to instead use <code>State</code>, like the above example: </p> <p> <pre>IState&lt;State,&nbsp;(Out1&nbsp;a,&nbsp;Out1&nbsp;b)&gt;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;a&nbsp;<span style="color:blue;">in</span>&nbsp;in1.Request1() &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;b&nbsp;<span style="color:blue;">in</span>&nbsp;in1.Request1() &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;(a,&nbsp;b); <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;s.Run(csa);</pre> </p> <p> Do this consistently, and you can eventually delete the <code>Context</code> class. </p> <h3 id="c92292ad071c4b468fa223d764d89ab8"> Further possible refactorings <a href="#c92292ad071c4b468fa223d764d89ab8" title="permalink">#</a> </h3> <p> With the <code>Context</code> class gone, you're left with the abstract <code>State</code> class and its implementers: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">State</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;StatePair&lt;State,&nbsp;Out1&gt;&nbsp;<span style="color:#74531f;">Handle1</span>(In1&nbsp;<span style="color:#1f377f;">in1</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">abstract</span>&nbsp;StatePair&lt;State,&nbsp;Out2&gt;&nbsp;<span style="color:#74531f;">Handle2</span>(In2&nbsp;<span style="color:#1f377f;">in2</span>); }</pre> </p> <p> One further change worth considering might be to change the abstract base class to an interface. </p> <p> In this article, I've considered the general case where the <code>State</code> class supports an arbitrary number of independent state transitions, symbolised by the methods <code>Handle1</code> and <code>Handle2</code>. With an arbitrary number of such state transitions, you would have additional methods up to <code>HandleN</code> for <em>N</em> independent state transitions. </p> <p> At the other extreme, you may have just a single polymorphic state transition function. My intuition tells me that that's more likely to be the case than one would think at first. </p> <h3 id="c53b386a92b04575b675272d2dc85365"> Relationship between pattern and monad <a href="#c53b386a92b04575b675272d2dc85365" title="permalink">#</a> </h3> <p> You can view the State design pattern as a combination of two common practices in object-oriented programming: Mutation and polymorphism. </p> <p> <img src="/content/binary/state-pattern-venn.png" alt="Venn diagram with the two sets mutation and polymorphism. The intersection is labelled state."> </p> <p> The patterns in <em>Design Patterns</em> rely heavily on mutation of object state. Most other 'good' object-oriented code tends to do likewise. </p> <p> Proper object-oriented code also makes good use of polymorphism. Again, refer to <em>Design Patterns</em> or a book like <a href="https://blog.ploeh.dk/ref/refactoring">Refactoring</a> for copious examples. </p> <p> I view the State pattern as the intersection of these two common practices. The problem to solve is this: </p> <blockquote> <p> "Allow an object to alter its behavior when its internal state changes." </p> <footer><cite><a href="/ref/dp">Design Patterns</a></cite></footer> </blockquote> <p> The State pattern achieves that goal by having an inner polymorphic object (<code>State</code>) wrapped by an container object (<code>Context</code>). The <code>State</code> objects can mutate the <code>Context</code>, which enables them to replace themselves with other states. </p> <p> While functional programming also has notions of polymorphism, a pure function can't mutate state. Instead, a pure function must return a new state, leaving the old state unmodified. If there's nothing else to return, you can model such state-changing behaviour as an <a href="https://en.wikipedia.org/wiki/Endomorphism">endomorphism</a>. The article <a href="/2021/05/31/from-state-tennis-to-endomorphism">From State tennis to endomorphism</a> gives a quite literal example of that. </p> <p> Sometimes, however, an object-oriented method does more than one thing: It both mutates state and returns a value. (This, by the way, violates <a href="https://en.wikipedia.org/wiki/Command%E2%80%93query_separation">the Command Query Separation principle</a>.) The State monad is the functional way of doing that: Return both the result and the new state. </p> <p> Essentially, you replace mutation with the State monad. </p> <p> <img src="/content/binary/state-monad-venn.png" alt="Venn diagram with the two sets state monad and polymorphism. The intersection is labelled state."> </p> <p> From a functional perspective, then, we can view the State pattern as the intersection of polymorphism and the State monad. </p> <h3 id="d31601e4146d4f48ae30228f697de0a0"> Examples <a href="#d31601e4146d4f48ae30228f697de0a0" title="permalink">#</a> </h3> <p> This article is both long and abstract. Some examples might be helpful, so I'll give a few in separate articles: <ul> <li><a href="/2022/09/26/refactoring-the-tcp-state-pattern-example-to-pure-functions">Refactoring the TCP State pattern example to pure functions</a></li> <li>Refactoring a saga from the State pattern to the State monad</li> </ul> The first one uses the example from <em>Design Patterns</em>. That example is, unfortunately not that illuminating, since none of the book's methods return data. Thus, the endomorphism-based refactoring is enough, and you don't need the State monad. Therefore, another example is warranted. </p> <h3 id="1b5dead7f5c84f3896d639837314f17d"> Conclusion <a href="#1b5dead7f5c84f3896d639837314f17d" title="permalink">#</a> </h3> <p> You can view the State design pattern as the intersection of polymorphism and mutation. Both are object-oriented staples. The pattern uses polymorphism to model state, and mutation to change from one polymorphic state to another. </p> <p> In functional programming pure functions can't mutate state. You can often design around that problem, but if all else fails, the State monad offers a general-purpose alternative to both return a value and change object state. Thus, you can view the functional equivalent of the State pattern as the intersection of polymorphism and the State monad. </p> <p> <strong>Next:</strong> <a href="/2022/09/26/refactoring-the-tcp-state-pattern-example-to-pure-functions">Refactoring the TCP State pattern example to 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>. Natural transformations as invariant functors https://blog.ploeh.dk/2022/08/29/natural-transformations-as-invariant-functors 2022-08-29T06:12:00+00:00 Mark Seemann <div id="post"> <p> <em>An article (also) for object-oriented programmers.</em> </p> <ins datetime="2022-09-04T06:40Z"> <p> <strong>Update 2022-09-04:</strong> <em>This article is most likely partially incorrect. What it describes works, but may not be a natural transformation. See <a href="#9336107b26fd48a8971e617d8ebd5159">the below comment</a> for more details.</em> </p> </ins> <p> This article is part of <a href="/2022/08/01/invariant-functors">a series of articles about invariant functors</a>. An invariant functor is a <a href="/2018/03/22/functors">functor</a> that is neither covariant nor contravariant. See the series introduction for more details. The <a href="/2022/08/08/endomorphism-as-an-invariant-functor">previous article</a> described how you can view an <a href="https://en.wikipedia.org/wiki/Endomorphism">endomorphism</a> as an invariant functor. This article generalises that result. </p> <h3 id="f3a2cab08b004fe2bfa8e4b307317d88"> Endomorphism as a natural transformation <a href="#f3a2cab08b004fe2bfa8e4b307317d88" title="permalink">#</a> </h3> <p> An endomorphism is a function whose <a href="https://en.wikipedia.org/wiki/Domain_of_a_function">domain</a> and <a href="https://en.wikipedia.org/wiki/Codomain">codomain</a> is the same. In C# you'd denote the type as <code>Func&lt;T, T&gt;</code>, in <a href="https://fsharp.org/">F#</a> as <code>'a -&gt; 'a</code>, and in <a href="https://www.haskell.org/">Haskell</a> as <code>a -&gt; a</code>. <code>T</code>, <code>'a</code>, and <code>a</code> all symbolise generic types - the notation is just different, depending on the language. </p> <p> A 'naked' value is isomorphic to <a href="/2018/09/03/the-identity-functor">the Identity functor</a>. You can wrap a value of the type <code>a</code> in <code>Identity a</code>, and if you have an <code>Identity a</code>, you can extract the <code>a</code> value. </p> <p> An endomorphism is thus isomorphic to a function from Identity to Identity. In C#, you might denote that as <code>Func&lt;Identity&lt;T&gt;, Identity&lt;T&gt;&gt;</code>, and in Haskell as <code>Identity a -&gt; Identity a</code>. </p> <p> In fact, you can lift any function to an Identity-valued function: </p> <p> <pre>Prelude Data.Functor.Identity&gt; :t \f -&gt; Identity . f . runIdentity \f -&gt; Identity . f . runIdentity :: (b -&gt; a) -&gt; Identity b -&gt; Identity a</pre> </p> <p> While this is a general result that allows <code>a</code> and <code>b</code> to differ, when <code>a ~ b</code> this describes an endomorphism. </p> <p> Since Identity is a functor, a function <code>Identity a -&gt; Identity a</code> is a <a href="/2022/07/18/natural-transformations">natural transformation</a>. </p> <p> The identity function (<code>id</code> in F# and Haskell; <code>x =&gt; x</code> in C#) is the only one possible entirely general endomorphism. You can use the <a href="https://hackage.haskell.org/package/natural-transformation">natural-transformation</a> package to make it explicit that this is a natural transformation: </p> <p> <pre><span style="color:#2b91af;">idNT</span>&nbsp;::&nbsp;<span style="color:blue;">Identity</span>&nbsp;:~&gt;&nbsp;<span style="color:blue;">Identity</span> idNT&nbsp;=&nbsp;NT&nbsp;$&nbsp;Identity&nbsp;.&nbsp;<span style="color:blue;">id</span>&nbsp;.&nbsp;runIdentity</pre> </p> <p> The point, so far, is that you can view an endomorphism as a natural transformation. </p> <p> Since an endomorphism forms an invariant functor, this suggests a promising line of inquiry. </p> <h3 id="88842564359c40978adb687e27cc460d"> Natural transformations as invariant functors <a href="#88842564359c40978adb687e27cc460d" title="permalink">#</a> </h3> <p> Are <em>all</em> natural transformations invariant functors? </p> <p> Yes, they are. In Haskell, you can implement it like this: </p> <p> <pre><span style="color:blue;">instance</span>&nbsp;(<span style="color:blue;">Functor</span>&nbsp;f,&nbsp;<span style="color:blue;">Functor</span>&nbsp;g)&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;<span style="color:blue;">Invariant</span>&nbsp;(<span style="color:blue;">NT</span>&nbsp;f&nbsp;g)&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;invmap&nbsp;f&nbsp;g&nbsp;(NT&nbsp;h)&nbsp;=&nbsp;NT&nbsp;$&nbsp;<span style="color:blue;">fmap</span>&nbsp;f&nbsp;.&nbsp;h&nbsp;.&nbsp;<span style="color:blue;">fmap</span>&nbsp;g</pre> </p> <p> Here, I chose to define <code>NT</code> from scratch, rather than relying on the <em>natural-transformation</em> package. </p> <p> <pre><span style="color:blue;">newtype</span>&nbsp;NT&nbsp;f&nbsp;g&nbsp;a&nbsp;=&nbsp;NT&nbsp;{&nbsp;unNT&nbsp;::&nbsp;f&nbsp;a&nbsp;-&gt;&nbsp;g&nbsp;a&nbsp;}</pre> </p> <p> Notice how the implementation (<code><span style="color:blue;">fmap</span>&nbsp;f&nbsp;.&nbsp;h&nbsp;.&nbsp;<span style="color:blue;">fmap</span>&nbsp;g</code>) looks like a generalisation of the endomorphism implementation of <code>invmap</code> (<code>f . h . g</code>). Instead of pre-composing with <code>g</code>, the generalisation pre-composes with <code>fmap g</code>, and instead of post-composing with <code>f</code>, it post-composes with <code>fmap f</code>. </p> <p> Using the same kind of diagram as in the previous article, this composition now looks like this: </p> <p> <img src="/content/binary/invariant-natural-transformation-map-diagram.png" alt="Arrow diagram showing the mapping from a natural transformation in a to a natural transformation in b."> </p> <p> I've used thicker arrows to indicate that each one potentially involves 'more work'. Each is a mapping from a functor to a functor. For the <a href="/2022/04/19/the-list-monad">List functor</a>, for example, the arrow implies zero to many values being mapped. Thus, 'more data' moves 'through' each arrow, and for that reason I thought it made sense to depict them as being thicker. This 'more data' view is not always correct. For example, for <a href="/2018/03/26/the-maybe-functor">the Maybe functor</a>, the amount of data transported though each arrow is zero or one, which rather suggests a thinner arrow. For something like <a href="/2021/07/19/the-state-functor">the State functor</a> or <a href="/2021/08/30/the-reader-functor">the Reader functor</a>, there's really no <em>data</em> in the strictest sense moving through the arrows, but rather functions (which are also, however, a kind of data). Thus, don't take this metaphor of the thicker arrows literally. I did, however, wish to highlight that there's something 'more' going on. </p> <p> The diagram shows a natural transformation <code>h</code> from some functor <code>F</code> to another functor <code>G</code>. It transports objects of the type <code>a</code>. If <code>a</code> and <code>b</code> are isomorphic, you can map that natural transformation to one that transports objects of the type <code>b</code>. </p> <p> Compared to endomorphisms, where you need to, say, map <code>b</code> to <code>a</code>, you now need to map <code>F b</code> to <code>F a</code>. If <code>g</code> maps <code>b</code> to <code>a</code>, then <code>fmap g</code> maps <code>F b</code> to <code>F a</code>. The same line of argument applies to <code>fmap f</code>. </p> <p> In C# you can implement the same behaviour as follows. Assume that you have a natural transformation <code>H</code> from the functor <code>F</code> to the functor <code>G</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Func&lt;F&lt;A&gt;,&nbsp;G&lt;A&gt;&gt;&nbsp;H&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;}</pre> </p> <p> You can now implement a non-standard <code>Select</code> overload (as described in the introductory article) that maps a natural transformation <code>FToG&lt;A&gt;</code> to a natural transformation <code>FToG&lt;B&gt;</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;FToG&lt;B&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">B</span>&gt;(Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">aToB</span>,&nbsp;Func&lt;B,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">bToA</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;FToG&lt;B&gt;(<span style="color:#1f377f;">fb</span>&nbsp;=&gt;&nbsp;H(fb.Select(bToA)).Select(aToB)); }</pre> </p> <p> The implementation looks more imperative than in Haskell, but the idea is the same. First it uses <code>Select</code> on <code>F</code> in order to translate <code>fb</code> (of the type <code>F&lt;B&gt;</code>) to an <code>F&lt;A&gt;</code>. It then uses <code>H</code> to transform the <code>F&lt;A&gt;</code> to an <code>G&lt;A&gt;</code>. Finally, now that it has a <code>G&lt;A&gt;</code>, it can use <code>Select</code> on <em>that</em> functor to map to a <code>G&lt;B&gt;</code>. </p> <p> Note that there's two different functors (<code>F</code> and <code>G</code>) in play, so the two <code>Select</code> methods are different. This is also true in the Haskell code. <code>fmap g</code> need not be the same as <code>fmap f</code>. </p> <h3 id="70c39c1999864a82a73a4ce22f252110"> Identity law <a href="#70c39c1999864a82a73a4ce22f252110" title="permalink">#</a> </h3> <p> As in the previous article, I'll set out to <em>prove</em> the two laws for invariant functors, starting with the identity law. Again, I'll use equational reasoning with <a href="https://bartoszmilewski.com/2015/01/20/functors/">the notation that Bartosz Milewski uses</a>. Here's the proof that the <code>invmap</code> instance obeys the identity law: </p> <p> <pre>&nbsp;&nbsp;invmap&nbsp;id&nbsp;id&nbsp;(NT&nbsp;h) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;invmap&nbsp;} &nbsp;&nbsp;NT&nbsp;$&nbsp;fmap&nbsp;id&nbsp;.&nbsp;h&nbsp;.&nbsp;fmap&nbsp;id =&nbsp;{&nbsp;first&nbsp;functor&nbsp;law&nbsp;} &nbsp;&nbsp;NT&nbsp;$&nbsp;id&nbsp;.&nbsp;h&nbsp;.&nbsp;id =&nbsp;{&nbsp;eta&nbsp;expansion&nbsp;} &nbsp;&nbsp;NT&nbsp;$&nbsp;(\x&nbsp;-&gt;&nbsp;(id&nbsp;.&nbsp;h&nbsp;.&nbsp;id)&nbsp;x) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;(.)&nbsp;} &nbsp;&nbsp;NT&nbsp;$&nbsp;(\x&nbsp;-&gt;&nbsp;id(h(id(x)))) =&nbsp;{&nbsp;defintion&nbsp;of&nbsp;id&nbsp;} &nbsp;&nbsp;NT&nbsp;$&nbsp;(\x&nbsp;-&gt;&nbsp;h(x)) =&nbsp;{&nbsp;eta&nbsp;reduction&nbsp;} &nbsp;&nbsp;NT&nbsp;h =&nbsp;{&nbsp;definition&nbsp;of&nbsp;id&nbsp;} &nbsp;&nbsp;id&nbsp;(NT&nbsp;h)</pre> </p> <p> I'll leave it here without further comment. The Haskell type system is so expressive and abstract that it makes little sense to try to translate these findings to C# or F# in the abstract. Instead, you'll see some more concrete examples later. </p> <h3 id="d54ff79951db44559583a200d20cf6d9"> Composition law <a href="#d54ff79951db44559583a200d20cf6d9" title="permalink">#</a> </h3> <p> As with the identity law, I'll offer a proof for the composition law for the Haskell instance: </p> <p> <pre>&nbsp;&nbsp;invmap&nbsp;f2&nbsp;f2&#39;&nbsp;$&nbsp;invmap&nbsp;f1&nbsp;f1&#39;&nbsp;(NT&nbsp;h) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;invmap&nbsp;} &nbsp;&nbsp;invmap&nbsp;f2&nbsp;f2&#39;&nbsp;$&nbsp;NT&nbsp;$&nbsp;fmap&nbsp;f1&nbsp;.&nbsp;h&nbsp;.&nbsp;fmap&nbsp;f1&#39; =&nbsp;{&nbsp;defintion&nbsp;of&nbsp;($)&nbsp;} &nbsp;&nbsp;invmap&nbsp;f2&nbsp;f2&#39;&nbsp;(NT&nbsp;(fmap&nbsp;f1&nbsp;.&nbsp;h&nbsp;.&nbsp;fmap&nbsp;f1&#39;)) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;invmap&nbsp;} &nbsp;&nbsp;NT&nbsp;$&nbsp;fmap&nbsp;f2&nbsp;.&nbsp;(fmap&nbsp;f1&nbsp;.&nbsp;h&nbsp;.&nbsp;fmap&nbsp;f1&#39;)&nbsp;.&nbsp;fmap&nbsp;f2&#39; =&nbsp;{&nbsp;associativity&nbsp;of&nbsp;composition&nbsp;(.)&nbsp;} &nbsp;&nbsp;NT&nbsp;$&nbsp;(fmap&nbsp;f2&nbsp;.&nbsp;fmap&nbsp;f1)&nbsp;.&nbsp;h&nbsp;.&nbsp;(fmap&nbsp;f1&#39;&nbsp;.&nbsp;fmap&nbsp;f2&#39;) =&nbsp;{&nbsp;second&nbsp;functor&nbsp;law&nbsp;} &nbsp;&nbsp;NT&nbsp;$&nbsp;fmap&nbsp;(f2&nbsp;.&nbsp;f1)&nbsp;.&nbsp;h&nbsp;.&nbsp;fmap&nbsp;(f1&#39;&nbsp;.&nbsp;f2&#39;) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;invmap&nbsp;} &nbsp;&nbsp;invmap&nbsp;(f2&nbsp;.&nbsp;f1)&nbsp;(f1&#39;&nbsp;.&nbsp;f2&#39;)&nbsp;(NT&nbsp;h)</pre> </p> <p> Unless I've made a mistake, these two proofs should demonstrate that all natural transformations can be turned into an invariant functor - in Haskell, at least, but I'll conjecture that that result carries over to other languages like F# and C# as long as one stays within the confines of <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. </p> <h3 id="2afc7c35819c4d499f531a7229102404"> The State functor as a natural transformation <a href="#2afc7c35819c4d499f531a7229102404" title="permalink">#</a> </h3> <p> I'll be honest and admit that my motivation for embarking on this exegesis was because I'd come to the realisation that you can think about <a href="/2021/07/19/the-state-functor">the State functor</a> as a natural transformation. Recall that <code>State</code> is usually defined like this: </p> <p> <pre><span style="color:blue;">newtype</span>&nbsp;State&nbsp;s&nbsp;a&nbsp;=&nbsp;State&nbsp;{&nbsp;runState&nbsp;::&nbsp;s&nbsp;-&gt;&nbsp;(a,&nbsp;s)&nbsp;}</pre> </p> <p> You can easily establish that this definition of <code>State</code> is isomorphic with a natural transformation from <a href="/2018/09/03/the-identity-functor">the Identity functor</a> to <a href="/2018/12/31/tuple-bifunctor">the tuple functor</a>: </p> <p> <pre><span style="color:#2b91af;">stateToNT</span>&nbsp;::&nbsp;<span style="color:blue;">State</span>&nbsp;s&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">NT</span>&nbsp;<span style="color:blue;">Identity</span>&nbsp;((,)&nbsp;a)&nbsp;s stateToNT&nbsp;(State&nbsp;h)&nbsp;=&nbsp;NT&nbsp;$&nbsp;h&nbsp;.&nbsp;runIdentity <span style="color:#2b91af;">ntToState</span>&nbsp;::&nbsp;<span style="color:blue;">NT</span>&nbsp;<span style="color:blue;">Identity</span>&nbsp;((,)&nbsp;a)&nbsp;s&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">State</span>&nbsp;s&nbsp;a ntToState&nbsp;(NT&nbsp;h)&nbsp;=&nbsp;State&nbsp;$&nbsp;h&nbsp;.&nbsp;Identity</pre> </p> <p> Notice that this is a natural transformation in <code>s</code> - not in <code>a</code>. </p> <p> Since I've already established that natural transformations form invariant functors, this also applies to the State monad. </p> <h3 id="6c0025936a9949eca6191989f4d1b8c6"> State mapping <a href="#6c0025936a9949eca6191989f4d1b8c6" title="permalink">#</a> </h3> <p> My point with all of this isn't really to insist that anyone makes actual use of all this machinery, but rather that this line of reasoning helps to <em>identify a capability</em>. We now know that it's possible to translate a <code>State s a</code> value to a <code>State t a</code> value if <code>s</code> is isomorphic to <code>t</code>. </p> <p> As an example, imagine that you have some State-valued function that attempts to find the maximum value based on various criteria. Such a <code>pickMax</code> function may have the type <code><span style="color:blue;">State</span>&nbsp;(<span style="color:blue;">Max</span>&nbsp;<span style="color:#2b91af;">Integer</span>)&nbsp;<span style="color:#2b91af;">String</span></code> where the state type (<code><span style="color:blue;">Max</span>&nbsp;<span style="color:#2b91af;">Integer</span></code>) is used to keep track of the maximum value found while examining candidates. </p> <p> You could conceivably turn such a function around to instead look for the minimum by mapping the state to a <code>Min</code> value instead: </p> <p> <pre><span style="color:#2b91af;">pickMin</span>&nbsp;::&nbsp;<span style="color:blue;">State</span>&nbsp;(<span style="color:blue;">Min</span>&nbsp;<span style="color:#2b91af;">Integer</span>)&nbsp;<span style="color:#2b91af;">String</span> pickMin&nbsp;=&nbsp;ntToState&nbsp;$&nbsp;invmap&nbsp;(Min&nbsp;.&nbsp;getMax)&nbsp;(Max&nbsp;.&nbsp;getMin)&nbsp;$&nbsp;stateToNT&nbsp;pickMax</pre> </p> <p> You can use <code>getMax</code> to extract the underlying <code>Integer</code> from the <code><span style="color:blue;">Max</span>&nbsp;<span style="color:#2b91af;">Integer</span></code> and then <code>Min</code> to turn it into a <code><span style="color:blue;">Min</span>&nbsp;<span style="color:#2b91af;">Integer</span></code> value, and vice versa. <code><span style="color:blue;">Max</span>&nbsp;<span style="color:#2b91af;">Integer</span></code> and <code><span style="color:blue;">Min</span>&nbsp;<span style="color:#2b91af;">Integer</span></code> are isomorphic. </p> <p> In C#, you can implement a similar method. The code shown here extends the code shown in <a href="/2021/07/19/the-state-functor">The State functor</a>. I chose to call the method <code>SelectState</code> so as to not make things too confusing. The State functor already comes with a <code>Select</code> method that maps <code>T</code> to <code>T1</code> - that's the 'normal', covariant functor implementation. The new method is the invariant functor implementation that maps the state <code>S</code> to <code>S1</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;S1,&nbsp;T&gt;&nbsp;<span style="color:#74531f;">SelectState</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">S1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">state</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S,&nbsp;S1&gt;&nbsp;<span style="color:#1f377f;">sToS1</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S1,&nbsp;S&gt;&nbsp;<span style="color:#1f377f;">s1ToS</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;InvariantStateMapper&lt;T,&nbsp;S,&nbsp;S1&gt;(state,&nbsp;sToS1,&nbsp;s1ToS); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">InvariantStateMapper</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">S1</span>&gt;&nbsp;:&nbsp;IState&lt;S1,&nbsp;T&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;state; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;S,&nbsp;S1&gt;&nbsp;sToS1; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;S1,&nbsp;S&gt;&nbsp;s1ToS; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">InvariantStateMapper</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">state</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S,&nbsp;S1&gt;&nbsp;<span style="color:#1f377f;">sToS1</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S1,&nbsp;S&gt;&nbsp;<span style="color:#1f377f;">s1ToS</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.state&nbsp;=&nbsp;state; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.sToS1&nbsp;=&nbsp;sToS1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.s1ToS&nbsp;=&nbsp;s1ToS; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;T,&nbsp;S1&gt;&nbsp;<span style="color:#74531f;">Run</span>(S1&nbsp;<span style="color:#1f377f;">s1</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;state.Run(s1ToS(s1)).Select(sToS1); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> As usual when working in C# with interfaces instead of higher-order functions, <a href="/2019/12/16/zone-of-ceremony">there's some ceremony to be expected</a>. The only interesting line of code is the <code>Run</code> implementation. </p> <p> It starts by calling <code>s1ToS</code> in order to translate the <code>s1</code> parameter into an <code>S</code> value. This enables it to call <code>Run</code> on <code>state</code>. The result is a tuple with the type <code>Tuple&lt;T,&nbsp;S&gt;</code>. It's necessary to translate the <code>S</code> to <code>S1</code> with <code>sToS1</code>. You could do that by extracting the value from the tuple, mapping it, and returning a new tuple. Since a tuple gives rise to a functor (<a href="/2018/12/31/tuple-bifunctor">two, actually</a>) I instead used the <code>Select</code> method I'd already defined on it. </p> <p> Notice how similar the implementation is to the implementation of <a href="/2022/08/08/endomorphism-as-an-invariant-functor">the endomorphism invariant functor</a>. The only difference is that when translating back from <code>S</code> to <code>S1</code>, this happens inside a <code>Select</code> mapping. This is as predicted by the general implementation of invariant functors for natural transformations. </p> <p> In a future article, you'll see an example of <code>SelectState</code> in action. </p> <h3 id="5a148244488b4391be257181108072b3"> Other natural transformations <a href="#5a148244488b4391be257181108072b3" title="permalink">#</a> </h3> <p> As the <a href="/2022/07/18/natural-transformations">natural transformations</a> article outlines, there are infinitely many natural transformations. Each one gives rise to an invariant functor. </p> <p> It might be a good exercise to try to implement a few of them as invariant functors. If you want to do it in C#, you could, for example, start with the <em>safe head</em> natural transformation. </p> <p> If you want to stick to interfaces, you could define one like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">ISafeHead</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;T&gt;&nbsp;<span style="color:#74531f;">TryFirst</span>(IEnumerable&lt;T&gt;&nbsp;<span style="color:#1f377f;">ts</span>); }</pre> </p> <p> The exercise is now to define and implement a method like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ISafeHead&lt;T1&gt;&nbsp;<span style="color:#74531f;">Select</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;ISafeHead&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;T1&gt;&nbsp;<span style="color:#1f377f;">tToT1</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">t1ToT</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Implementation&nbsp;goes&nbsp;here...</span> }</pre> </p> <p> The implementation, once you get the handle of it, is entirely automatable. After all, in Haskell it's possible to do it once and for all, as shown above. </p> <h3 id="2c86c2f77e0a404da80858d855898843"> Conclusion <a href="#2c86c2f77e0a404da80858d855898843" title="permalink">#</a> </h3> <p> A natural transformation forms an invariant functor. This may not be the most exciting result ever, because invariant functors are limited in use. They only work when translating between types that are already isomorphic. Still, I did <a href="/2022/09/05/the-state-pattern-and-the-state-monad">find a use for this result</a> when I was working with the relationship between the State design pattern and the <a href="/2022/06/20/the-state-monad">State monad</a>. </p> <p> <strong>Next:</strong> Functors as invariant functors. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="9336107b26fd48a8971e617d8ebd5159"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Due to feedback that I've received, I have to face evidence that this article may be partially incorrect. While I've added that proviso at the top of the article, I've decided to use a comment to expand on the issue. </p> <p> On Twitter, the user <a href="https://twitter.com/Savlambda">@Savlambda</a> (<em>borar</em>) argued that my <code>newtype</code> isn't a natural transformation: </p> <blockquote> <p> "The newtype 'NT' in the article is not a natural transformation though. Quantification over 'a' is at the "wrong place": it is not allowed for a client module to instantiate the container element type of a natural transformation." </p> <footer><cite><a href="https://twitter.com/Savlambda/status/1564175654845030400">@Savlambda</a></cite></footer> </blockquote> <p> While I engaged with the tweet, I have to admit that it took me a while to understand the core of the criticism. Of course I'm not happy about being wrong, but initially I genuinely didn't understand what was the problem. On the other hand, it's not the first time @Savlambda has provided valuable insights, so I knew it'd behove me to pay attention. </p> <p> After a few tweets back and forth, @Savlambda finally supplied a counter-argument that I understood. </p> <blockquote> <p> "This is not being overly pedantic. Here is one practical implication:" </p> <footer><cite><a href="https://twitter.com/Savlambda/status/1564970422981890048">@Savlambda</a></cite></footer> </blockquote> <p> The practical implication shown in the tweet is a screen shot (in order to get around Twitter's character limitation), but I'll reproduce it as code here in order to <a href="https://meta.stackoverflow.com/q/285551/126014">not show images of code</a>. </p> <p> <pre><span style="color:blue;">type</span>&nbsp;<span style="color:#2b91af;">(~&gt;)</span>&nbsp;f&nbsp;g&nbsp;=&nbsp;forall&nbsp;a.&nbsp;f&nbsp;a&nbsp;-&gt;&nbsp;g&nbsp;a <span style="color:green;">--&nbsp;Use&nbsp;the&nbsp;natural&nbsp;transformation&nbsp;twice,&nbsp;for&nbsp;different&nbsp;types </span><span style="color:#2b91af;">convertLists</span>&nbsp;::&nbsp;([]&nbsp;~&gt;&nbsp;g)&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;(g&nbsp;<span style="color:#2b91af;">Int</span>,&nbsp;g&nbsp;<span style="color:#2b91af;">Bool</span>) convertLists&nbsp;nt&nbsp;=&nbsp;(nt&nbsp;[1,2],&nbsp;nt&nbsp;[True]) <span style="color:blue;">newtype</span>&nbsp;NT&nbsp;f&nbsp;g&nbsp;a&nbsp;=&nbsp;NT&nbsp;(f&nbsp;a&nbsp;-&gt;&nbsp;g&nbsp;a) <span style="color:green;">--&nbsp;Does&nbsp;not&nbsp;type&nbsp;check,&nbsp;does&nbsp;not&nbsp;work;&nbsp;not&nbsp;a&nbsp;natural&nbsp;transformation </span><span style="color:#2b91af;">convertLists2</span>&nbsp;::&nbsp;<span style="color:blue;">NT</span>&nbsp;[]&nbsp;g&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;(g&nbsp;<span style="color:#2b91af;">Int</span>,&nbsp;g&nbsp;<span style="color:#2b91af;">Bool</span>) convertLists2&nbsp;(NT&nbsp;f)&nbsp;=&nbsp;(f&nbsp;[1,2],&nbsp;f&nbsp;[True])</pre> </p> <p> I've moved the code comments to prevent horizontal scrolling, but otherwise tried to stay faithful to @Savlambda's screen shot. </p> <p> This was the example that finally hit the nail on the head for me. A natural transformation is a mapping from one functor (<code>f</code>) to another functor (<code>g</code>). I knew that already, but hadn't realised the implications. In Haskell (and other languages with <a href="https://en.wikipedia.org/wiki/Parametric_polymorphism">parametric polymorphism</a>) a <code>Functor</code> is defined for all <code>a</code>. </p> <p> A natural transformation is a higher level of abstraction, mapping one functor to another. That mapping must be defined for all <code>a</code>, and it must be <em>reusable</em>. The second example provided by @Savlambda demonstrates that the function wrapped by <code>NT</code> isn't reusable for different contained types. </p> <p> If you try to compile that example, GHC emits this compiler error: </p> <p> <pre>* Couldn't match type `a' with `Int' `a' is a rigid type variable bound by the type signature for: convertLists2 :: forall (g :: * -&gt; *) a. NT [] g a -&gt; (g Int, g Bool) Expected type: g Int Actual type: g a * In the expression: f [1, 2] In the expression: (f [1, 2], f [True]) In an equation for `convertLists2': convertLists2 (NT f) = (f [1, 2], f [True])</pre> </p> <p> Even though it's never fun to be proven wrong, I want to thank @Savlambda for educating me. One reason I write blog posts like this one is that writing is a way to learn. By writing about topics like these, I educate myself. Occasionally, it turns out that I make a mistake, and <a href="/2018/12/03/set-is-not-a-functor">this isn't the first time that's happened</a>. I also wish to apologise if this article has now left any readers more confused. </p> <p> A remaining question is what practical implications this has? Only rarely do you need a programming construct like <code>convertLists2</code>. On the other hand, had I wanted a function with the type <code>NT [] g Int -&gt; (g Int, g Int)</code>, it would have type-checked just fine. </p> <p> I'm not claiming that this is generally useful either, but I actually wrote this article because I <em>did</em> have use for the result that <code>NT</code> (whatever it is) is an invariant functor. As far as I can tell, that result still holds. </p> <p> I could be wrong about that, too. If you think so, please leave a comment. </p> </div> <div class="comment-date">2022-09-04 7:53 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>. Can types replace validation? https://blog.ploeh.dk/2022/08/22/can-types-replace-validation 2022-08-22T05:57:00+00:00 Mark Seemann <div id="post"> <p> <em>With some examples in C#.</em> </p> <p> In a comment to my article on <a href="/2022/08/15/aspnet-validation-revisited">ASP.NET validation revisited</a> Maurice Johnson asks: </p> <blockquote> <p> "I was just wondering, is it possible to use the type system to do the validation instead ? </p> <p> "What I mean is, for example, to make all the ReservationDto's field a type with validation in the constructor (like a class name, a class email, and so on). Normally, when the framework will build ReservationDto, it will try to construct the fields using the type constructor, and if there is an explicit error thrown during the construction, the framework will send us back the error with the provided message. </p> <p> "Plus, I think types like "email", "name" and "at" are reusable. And I feel like we have more possibilities for validation with that way of doing than with the validation attributes. </p> <p> "What do you think ?" </p> <footer><cite><a href="/2022/08/15/aspnet-validation-revisited#f6deac18851d47c3b066f82a8be3847d">Maurice Johnson</a></cite></footer> </blockquote> <p> I started writing a response below the question, but it grew and grew so I decided to turn it into a separate article. I think the question is of general interest. </p> <h3 id="2492a444e49b49a09a4f7c03f38b29d5"> The halting problem <a href="#2492a444e49b49a09a4f7c03f38b29d5" title="permalink">#</a> </h3> <p> I'm all in favour of using the type system for encapsulation, but there are limits to what it can do. We know this because it follows from the <a href="https://en.wikipedia.org/wiki/Halting_problem">halting problem</a>. </p> <p> I'm basing my understanding of the halting problem on <a href="https://www.goodreads.com/review/show/1731926050">my reading</a> of <a href="/ref/annotated-turing">The Annotated Turing</a>. In short, given an arbitrary computer program in a Turing-complete language, there's no general algorithm that will determine whether or not the program will finish running. </p> <p> A compiler that performs type-checking is a program, but typical type systems aren't Turing-complete. It's possible to write type checkers that always finish, because the 'programming language' they are running on - the type system - isn't Turing-complete. </p> <p> Normal type systems (like C#'s) aren't Turing-complete. You expect the C# compiler to always arrive at a result (either compiled code or error) in finite time. As a counter-example, consider <a href="https://www.haskell.org/">Haskell</a>'s type system. By default it, too, isn't Turing-complete, but with sufficient language extensions, you <em>can</em> make it Turing-complete. Here's a fun example: <a href="https://aphyr.com/posts/342-typing-the-technical-interview">Typing the technical interview</a> by Kyle Kingsbury (Aphyr). When you make the type system Turing-complete, however, termination is no longer guaranteed. A program may now compile forever or, practically, until it times out or runs out of memory. That's what happened to me when I tried to compile Kyle Kingsbury's code example. </p> <p> How is this relevant? </p> <p> This matters because understanding that a normal type system is <em>not</em> Turing-complete means that there are truths it <em>can't</em> express. Thus, we shouldn't be surprised if we run into rules or policies that we can't express with the type system we're given. What exactly is inexpressible depends on the type system. There are policies you can express in Haskell that are impossible to express in C#, and so on. Let's stick with C#, though. Here are some examples of rules that are practically inexpressible: </p> <ul> <li>An integer must be positive.</li> <li>A string must be at most 100 characters long.</li> <li>A maximum value must be greater than a minimum value.</li> <li>A value must be a valid email address.</li> </ul> <p> <a href="https://www.hillelwayne.com/">Hillel Wayne</a> provides more compelling examples in the article <a href="https://buttondown.email/hillelwayne/archive/making-illegal-states-unrepresentable/">Making Illegal States Unrepresentable</a>. </p> <h3 id="34f9d2e5570842adbb79a20972f458a0"> Encapsulation <a href="#34f9d2e5570842adbb79a20972f458a0" title="permalink">#</a> </h3> <p> Depending on how many times you've been around the block, you may find the above list naive. You may, for example, say that it's possible to express that an integer is positive like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">NaturalNumber</span>&nbsp;:&nbsp;IEquatable&lt;NaturalNumber&gt; { &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;i; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">NaturalNumber</span>(<span style="color:blue;">int</span>&nbsp;candidate) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(candidate&nbsp;&lt;&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentOutOfRangeException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(candidate), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;The&nbsp;value&nbsp;must&nbsp;be&nbsp;a&nbsp;positive&nbsp;(non-zero)&nbsp;number,&nbsp;but&nbsp;was:&nbsp;</span>{candidate}<span style="color:#a31515;">.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.i&nbsp;=&nbsp;candidate; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Various&nbsp;other&nbsp;members&nbsp;follow...</span></pre> </p> <p> I like introducing wrapper types like this. To the inexperienced developer this may seem redundant, but using a wrapper like this has several advantages. For one, it makes preconditions explicit. Consider a constructor like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Reservation</span>( &nbsp;&nbsp;&nbsp;&nbsp;Guid&nbsp;id, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;at, &nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;email, &nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;name, &nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber&nbsp;quantity)</pre> </p> <p> What are the preconditions that you, as a client developer, has to fulfil before you can create a valid <code>Reservation</code> object? First, you must supply five arguments: <code>id</code>, <code>at</code>, <code>email</code>, <code>name</code>, and <code>quantity</code>. There is, however, more information than that. </p> <p> Consider, as an alternative, a constructor like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Reservation</span>( &nbsp;&nbsp;&nbsp;&nbsp;Guid&nbsp;id, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;at, &nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;email, &nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;name, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;quantity)</pre> </p> <p> This constructor requires you to supply the same five arguments. There is, however, less explicit information available. If that was the only available constructor, you might be wondering: <em>Can I pass zero as <code>quantity</code>? Can I pass <code>-1</code>?</em> </p> <p> When the only constructor available is the first of these two alternatives, you already have the answer: No, the <code>quantity</code> must be a natural number. </p> <p> Another advantage of creating wrapper types like <code>NaturalNumber</code> is that you centralise run-time checks in one place. Instead of sprinkling defensive code all over the code base, you have it in one place. Any code that receives a <code>NaturalNumber</code> object knows that the check has already been performed. </p> <p> There's a word for this: <a href="/encapsulation-and-solid">Encapsulation</a>. </p> <p> You gather a coherent set of invariants and collect it in a single type, making sure that the type always guarantees its invariants. Note that this is an important design technique in functional programming too. While you may not have to worry about state mutation preserving invariants, it's still important to guarantee that all values of a type are <em>valid</em>. </p> <h3 id="8c48a55a5db74686ab7a0c8fc40dd650"> Predicative and constructive data <a href="#8c48a55a5db74686ab7a0c8fc40dd650" title="permalink">#</a> </h3> <p> It's debatable whether the above <code>NaturalNumber</code> class <em>really</em> uses the type system to model what constitutes valid data. Since it relies on a run-time predicate, it falls in the category of types Hillel Wayne <a href="https://www.hillelwayne.com/post/constructive/">calls <em>predicative</em></a>. Such types are easy to create and compose well, but on the other hand fail to take full advantage of the type system. </p> <p> It's often worthwhile considering if a <em>constructive</em> design is possible and practical. In other words, is it possible to <a href="https://blog.janestreet.com/effective-ml-video/">make illegal states unrepresentable</a> (MISU)? </p> <p> What's wrong with <code>NaturalNumber</code>? Doesn't it do that? No, it doesn't, because this compiles: </p> <p> <pre><span style="color:blue;">new</span>&nbsp;NaturalNumber(-1)</pre> </p> <p> Surely it <em>will</em> fail at run time, but it compiles. Thus, it's <em>representable</em>. </p> <p> <a href="/2011/04/29/Feedbackmechanismsandtradeoffs">The compiler gives you feedback faster than tests</a>. Considering MISU is worthwhile. </p> <p> Can we model natural numbers in a constructive way? Yes, with <a href="https://en.wikipedia.org/wiki/Peano_axioms">Peano numbers</a>. This is even <a href="/2018/05/28/church-encoded-natural-numbers">possible in C#</a>, but I wouldn't consider it practical. On the other hand, while it's possible to represent any natural number, there is <em>no way</em> to express -1 as a Peano number. </p> <p> As Hillel Wayne describes, constructive data types are much harder and requires a considerable measure of creativity. Often, a constructive model can seem impossible until you get a good idea. </p> <blockquote> <p> "a list can only be of even length. Most languages will not be able to express such a thing in a reasonable way in the data type." </p> <footer><cite><a href="https://note89.github.io/state-of-emergency/">Nils Eriksson</a></cite></footer> </blockquote> <p> Such a requirement may look difficult until inspiration hits. Then one day you may realise that it'd be as simple as a list of pairs (two-tuples). In Haskell, it could be as simple as this: </p> <p> <pre>newtype EvenList a = EvenList [(a,a)] deriving (Eq, Show)</pre> </p> <p> With such a constructive data model, lists of uneven length are unrepresentable. This is a simple example of the kind of creative thinking you may need to engage in with constructive data modelling. </p> <p> If you feel the need to object that Haskell isn't 'most languages', then here's the same idea expressed 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;">EvenCollection</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;:&nbsp;IEnumerable&lt;T&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IEnumerable&lt;Tuple&lt;T,&nbsp;T&gt;&gt;&nbsp;values; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">EvenCollection</span>(IEnumerable&lt;Tuple&lt;T,&nbsp;T&gt;&gt;&nbsp;<span style="color:#1f377f;">values</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.values&nbsp;=&nbsp;values; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IEnumerator&lt;T&gt;&nbsp;<span style="color:#74531f;">GetEnumerator</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">foreach</span>&nbsp;(var&nbsp;<span style="color:#1f377f;">x</span>&nbsp;<span style="color:#8f08c4;">in</span>&nbsp;values) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;x.Item1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;x.Item2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;IEnumerator&nbsp;IEnumerable.<span style="color:#74531f;">GetEnumerator</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;GetEnumerator(); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> You can create such a list like this: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">list</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;EvenCollection&lt;<span style="color:blue;">string</span>&gt;(<span style="color:blue;">new</span>[] { &nbsp;&nbsp;&nbsp;&nbsp;Tuple.Create(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;Tuple.Create(<span style="color:#a31515;">&quot;baz&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;qux&quot;</span>) });</pre> </p> <p> On the other hand, this doesn't compile: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">list</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;EvenCollection&lt;<span style="color:blue;">string</span>&gt;(<span style="color:blue;">new</span>[] { &nbsp;&nbsp;&nbsp;&nbsp;Tuple.Create(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;Tuple.Create(<span style="color:#a31515;">&quot;baz&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;qux&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;quux&quot;</span>) });</pre> </p> <p> Despite this digression, the point remains: Constructive data modelling may be impossible, unimagined, or impractical. </p> <p> Often, in languages like C# we resort to predicative data modelling. That's also what I did in the article <a href="/2022/08/15/aspnet-validation-revisited">ASP.NET validation revisited</a>. </p> <h3 id="830f3f7a663b459994cc585ef9604d11"> Validation as functions <a href="#830f3f7a663b459994cc585ef9604d11" title="permalink">#</a> </h3> <p> That was a long rambling detour inspired by a simple question: Is it possible to use types instead of validation? </p> <p> In order to address that question, it's only proper to explicitly state assumptions and definitions. What's the definition of <em>validation?</em> </p> <p> I'm not aware of a ubiquitous definition. While I could draw from <a href="https://en.wikipedia.org/wiki/Data_validation">the Wikipedia article on the topic</a>, at the time of writing it doesn't cite any sources when it sets out to define what it is. So I may as well paraphrase. It seems fair, though, to consider the stem of the word: <em>Valid</em>. </p> <p> Validation is the process of examining input to determine whether or not it's valid. I consider this a (mostly) self-contained operation: Given the data, is it well-formed and according to specification? If you have to query a database before making a decision, you're not validating the input. In that case, you're applying a business rule. As a rule of thumb I expect validations to be <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. </p> <p> Validation, then, seems to imply a process. Before you execute the process, you don't know if data is valid. After executing the process, you do know. </p> <p> Data types, whether predicative like <code>NaturalNumber</code> or constructive like <code>EvenCollection&lt;T&gt;</code>, aren't processes or functions. They are results. </p> <p> <img src="/content/binary/validation-as-a-function-from-data-to-type.png" alt="An arrow labelled 'validation' pointing from a document to the left labelled 'Data' to a box to the right labelled 'Type'."> </p> <p> Sometimes an algorithm can use a type to <em>infer</em> the validation function. This is common in statically typed languages, from C# over <a href="https://fsharp.org/">F#</a> to Haskell (which are the languages with which I'm most familiar). </p> <h3 id="4cc324c1919e45958542bb82c2ca73d4"> Data Transfer Object as a validation DSL <a href="#4cc324c1919e45958542bb82c2ca73d4" title="permalink">#</a> </h3> <p> In a way you can think of the type system as a <a href="https://en.wikipedia.org/wiki/Domain-specific_language">domain-specific language</a> (DSL) for defining validation functions. It's not perfectly suited for that task, but often good enough that many developers reach for it. </p> <p> Consider the <code>ReservationDto</code> class from the <a href="/2022/08/15/aspnet-validation-revisited">ASP.NET validation revisited</a> article where I eventually gave up on it: </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;Guid?&nbsp;Id&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;[Required,&nbsp;NotNull] &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;DateTime?&nbsp;At&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;[Required,&nbsp;NotNull] &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;[NaturalNumber] &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> It actually tries to do what Maurice Johnson suggests. Particularly, it defines <code>At</code> as a <code>DateTime?</code> value. </p> <p> <pre>&gt; <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">json</span>&nbsp;=&nbsp;<span style="color:#a31515;">&quot;{&nbsp;\&quot;At\&quot;:&nbsp;\&quot;2022-10-11T19:30\&quot;,&nbsp;\&quot;Email\&quot;:&nbsp;\&quot;z@example.com\&quot;,&nbsp;\&quot;Quantity\&quot;:&nbsp;1}&quot;</span>; &gt; JsonSerializer.Deserialize&lt;ReservationDto&gt;(json) ReservationDto { At=[11.10.2022 19:30:00], Email="z@example.com", Id=null, Name=null, Quantity=1 }</pre> </p> <p> A JSON deserializer like this one uses run-time reflection to examine the type in question and then maps the incoming data onto an instance. Many XML deserializers work the same way. </p> <p> What happens if you supply malformed input? </p> <p> <pre>&gt; <span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">json</span>&nbsp;=&nbsp;<span style="color:#a31515;">&quot;{&nbsp;\&quot;At\&quot;:&nbsp;\&quot;foo\&quot;,&nbsp;\&quot;Email\&quot;:&nbsp;\&quot;z@example.com\&quot;,&nbsp;\&quot;Quantity\&quot;:&nbsp;1}&quot;</span>; &gt; JsonSerializer.Deserialize&lt;ReservationDto&gt;(json) <span style="color:red">System.Text.Json.JsonException:↩ The JSON value could not be converted to System.Nullable`1[System.DateTime].↩ Path: $.At | LineNumber: 0 | BytePositionInLine: 26.↩ [...]</span></pre> </p> <p> (I've wrapped the result over multiple lines for readability. The <code>↩</code> symbol indicates where I've wrapped the text. I've also omitted a stack trace, indicated by <code>[...]</code>. I'll do that repeatedly throughout this article.) </p> <p> What happens if we try to define <code>ReservationDto.Quantity</code> with <code>NaturalNumber</code>? </p> <p> <pre>&gt; var json = "{ \"At\": \"2022-10-11T19:30\", \"Email\": \"z@example.com\", \"Quantity\": 1}"; &gt; JsonSerializer.Deserialize&lt;ReservationDto&gt;(json) <span style="color:red">System.Text.Json.JsonException:↩ The JSON value could not be converted to NaturalNumber.↩ Path: $.Quantity | LineNumber: 0 | BytePositionInLine: 67.↩ [...]</span></pre> </p> <p> While <a href="https://docs.microsoft.com/dotnet/api/system.text.json.jsonserializer">JsonSerializer</a> is a sophisticated piece of software, it's not so sophisticated that it can automatically map <code>1</code> to a <code>NaturalNumber</code> value. </p> <p> I'm sure that you can configure the behaviour with one or more <a href="https://docs.microsoft.com/dotnet/api/system.text.json.serialization.jsonconverter">JsonConverter</a> objects, but this is exactly the kind of framework <a href="https://en.wikipedia.org/wiki/Whac-A-Mole">Whack-a-mole</a> that I consider costly. It also suggests a wider problem. </p> <h3 id="bdad63c97ad44f1199f4f06e2b2e3fff"> Error handling <a href="#bdad63c97ad44f1199f4f06e2b2e3fff" title="permalink">#</a> </h3> <p> What happens if input to a validation function is malformed? You may want to report the errors to the caller, and you may want to report all errors in one go. Consider the user experience if you don't: A user types in a big form and submits it. The system informs him or her that there's an error in the third field. Okay, correct the error and submit again. Now there's an error in the fifth field, and so on. </p> <p> It's often better to return all errors as one collection. </p> <p> The problem is that type-based validation doesn't <em>compose</em> well. What do I mean by that? </p> <p> It's fairly clear that if you take a <em>simple</em> (i.e. non-complex) type like <code>NaturalNumber</code>, if you fail to initialize a value it's because the input is at fault: </p> <p> <pre>&gt; <span style="color:blue;">new</span>&nbsp;NaturalNumber(-1) <span style="color:red">System.ArgumentOutOfRangeException: The value must be a positive (non-zero) number, but was: -1.↩ (Parameter 'candidate') + NaturalNumber..ctor(int)</span></pre> </p> <p> The problem is that for complex types (i.e. types made from other types), exceptions short-circuit. As soon as one exception is thrown, further data validation stops. The <a href="/2022/08/15/aspnet-validation-revisited">ASP.NET validation revisited</a> article shows examples of that particular problem. </p> <p> This happens when validation functions have no composable way to communicate errors. When throwing exceptions, you can return an exception message, but exceptions short-circuit rather than compose. The same is true for the <a href="/2022/05/09/an-either-monad">Either monad</a>: It short-circuits. Once you're on <a href="https://fsharpforfunandprofit.com/posts/recipe-part2/">the failure track</a> you stay there and no further processing takes place. Errors don't compose. </p> <h3 id="7a85a7339fc24eda8e922ba12fdb3d89"> Monoidal versus applicative validation <a href="#7a85a7339fc24eda8e922ba12fdb3d89" title="permalink">#</a> </h3> <p> The naive take on validation is to answer the question: <em>Is that data valid or invalid?</em> Notice the binary nature of the question. It's either-or. </p> <p> This is true for both predicative data and constructive data. </p> <p> For constructive data, the question is: Is a candidate value representable? For example, can you represent <em>-1</em> as a Peano number? The answer is either yes or no; true or false. </p> <p> This is even clearer for predicative data, which is defined by a <em>predicate</em>. (Here's another <a href="/2021/09/09/the-specification-contravariant-functor">example of a natural number specification</a>.) A predicate is a function that returns a Boolean value: True or false. </p> <p> It's possible to compose Boolean values. The composition that we need in this case is Boolean <em>and</em>, which is also known as the <em>all</em> <a href="/2017/10/06/monoids">monoid</a>: If all values are <em>true</em>, the composed value is <em>true</em>; if just one value is <em>false</em>, the composed value is <em>false</em>. </p> <p> The problem is that during composition, we lose information. While a single <em>false</em> value causes the entire aggregated value to be <em>false</em>, we don't know why. And we don't know if there was only a single <em>false</em> value, or if there were more than one. Boolean <em>all</em> short-circuits on the first <em>false</em> value it encounters, and stops processing subsequent predicates. </p> <p> In logic, that's all you need, but in data validation you often want to know <em>what's wrong with the data</em>. </p> <p> Fortunately, this is <a href="/2020/12/14/validation-a-solved-problem">a solved problem</a>. Use <a href="/2018/11/05/applicative-validation">applicative validation</a>, an example of which I supplied in the article <a href="/2022/07/25/an-applicative-reservation-validation-example-in-c">An applicative reservation validation example in C#</a>. </p> <p> This changes focus on validation. No longer is validation a <em>true/false</em> question. Validation is a function from less-structured data to more-structured data. <a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/">Parse, don't validate</a>. </p> <h3 id="96d5b6c4df424f79b9eec8b186a2b3de"> Conclusion <a href="#96d5b6c4df424f79b9eec8b186a2b3de" title="permalink">#</a> </h3> <p> Can types replace validation? </p> <p> In some cases they can, but I think that the general answer is <em>no</em>. Granted, this answer is partially based on capabilities of current deserialisers. <a href="https://docs.microsoft.com/dotnet/api/system.text.json.jsonserializer.deserialize">JsonSerializer.Deserialize</a> short-circuits on the first error it encounters, and the same does <a href="https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html">aeson</a>'s <a href="https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#v:eitherDecode">eitherDecode</a>. </p> <p> While that's the current state of affairs, it may not have to stay like that forever. One might be able to derive an applicative parser from a desired destination type, but I haven't seen that done yet. </p> <p> It sounds like a worthwhile research project. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="4e4498fcf878443e96fad490569a8e4f"> <div class="comment-author"><a href="https://www.lloydatkinson.net">Lloyd Atkinson</a></div> <div class="comment-content"> <p> This slightly reminds me of <a href="https://github.com/colinhacks/zod">Zod</a> which is described as "TypeScript-first schema validation with static type inference". </p> <p> The library automatically infers a type that matches the validation - in a way it blurs this line between types and validation by making them become one. </p> <p> Of course, once you have that infered type there is nothing stopping you using it without the library, but that's something code reviews could catch. It's quite interesting though. </p> <pre> <code> import { z } from 'zod'; const User = z.object({ username: z.string(), age: z.number().positive({ message: 'Your age must be positive!', }), }); User.parse({ username: 'Ludwig', age: -1 }); // extract the inferred type type User = z.infer<typeof User>; // { username: string, age: number } </code> </pre> </div> <div class="comment-date">2022-08-28 00:53 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>. ASP.NET validation revisited https://blog.ploeh.dk/2022/08/15/aspnet-validation-revisited 2022-08-15T05:48:00+00:00 Mark Seemann <div id="post"> <p> <em>Is the built-in validation framework better than applicative validation?</em> </p> <p> I recently published an article called <a href="/2022/07/25/an-applicative-reservation-validation-example-in-c">An applicative reservation validation example in C#</a> in which I describe how to use the universal abstractions of <a href="/2018/10/01/applicative-functors">applicative functors</a> and <a href="/2017/11/27/semigroups">semigroups</a> to implement reusable, composable validation. </p> <p> One reader reaction made me stop and think: </p> <blockquote> <p> "An exercise on how to reject 90% of the framework's existing services (*Validation) only to re implement them more poorly, by renouncing standardization, interoperability and globalization all for the glory of FP." </p> <footer><cite><a href="https://twitter.com/PopCatalin/status/1551478523981881349">PopCatalin</a></cite></footer> </blockquote> <p> (At the time of posting, the <a href="https://twitter.com/PopCatalin">PopCatalin Twitter account</a>'s display name was <em>Prime minister of truth™ カタリンポップ🇺🇦</em>, which I find unhelpful. The linked <a href="https://github.com/popcatalin81">GitHub account</a> locates the user in <a href="https://en.wikipedia.org/wiki/Cluj-Napoca">Cluj-Napoca</a>, a city I've <a href="/schedule">repeatedly visited for conferences</a> - the last time as recent as June 2022. I wouldn't be surprised if we've interacted, but if so, I'm sorry to say that I can't connect these accounts with one of the many wonderful people I've met there. In general, I'm getting a strong sarcastic vibe from that account, and I'm not sure whether or not to take <em>Pronouns kucf/fof</em> seriously. As the possibly clueless 51-year white male that I am, I will proceed with good intentions and to the best of my abilities.) </p> <p> That reply is an important reminder that I should once in a while check my assumptions. I'm aware that the ASP.NET framework comes with validation features, but I many years ago dismissed them because I found them inadequate. Perhaps, in the meantime, these built-in services have improved to the point that they are to be preferred over <a href="/2018/11/05/applicative-validation">applicative validation</a>. </p> <p> I decided to attempt to refactor the code to take advantage of the built-in ASP.NET validation to be able to compare the two approaches. This article is an experience report. </p> <h3 id="d4b2e6bdae494d0397866f683ddd64e9"> Requirements <a href="#d4b2e6bdae494d0397866f683ddd64e9" title="permalink">#</a> </h3> <p> In order to compare the two approaches, the ASP.NET-based validation should support the same validation features as the applicative validation example: </p> <ul> <li>The <code>At</code> property is required and should be a valid date and time. If it isn't, the validation message should report the problem and the offending input.</li> <li>The <code>Email</code> property should be required. If it's missing, the validation message should state so.</li> <li>The <code>Quantity</code> property is required and should be a natural number. If it isn't, the validation message should report the problem and the offending input.</li> </ul> <p> The <a href="/2022/07/25/an-applicative-reservation-validation-example-in-c">previous article</a> includes an interaction example that I'll repeat here for convenience: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 Content-Type: application/json {&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;large&quot;</span>,&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>,&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;-1&nbsp;} HTTP/1.1 400 Bad Request Invalid date or time: large. Email address is missing. Quantity must be a positive integer, but was: -1.</pre> </p> <p> ASP.NET validation formats the errors differently, as you'll see later in this article. That's not much of a concern, though: <a href="/2014/12/23/exception-messages-are-for-programmers">Error <em>messages</em> are for other developers</a>. They don't really have to be machine-readable or have a strict shape (as opposed to error <em>types</em>, which should be machine-readable). </p> <p> Reporting the offending values, as in <em>"Quantity must be a positive integer, but was: -1."</em> is part of the requirements. A REST API can make no assumptions about its clients. Perhaps one client is an unattended batch job that only logs errors. Logging offending values may be helpful to maintenance developers of such a batch job. </p> <h3 id="74d95aed3a5a40eb8f32ace05b0410a0"> Framework API <a href="#74d95aed3a5a40eb8f32ace05b0410a0" title="permalink">#</a> </h3> <p> The first observation to make about the ASP.NET validation API is that it's specific to ASP.NET. It's not a general-purpose API that you can use for other purposes. </p> <p> If, instead, you need to validate input to a console application, a background message handler, a batch job, or a desktop or phone app, you can't use that API. </p> <p> Perhaps each of these styles of software come with their own validation APIs, but even if so, that's a different API you'll have to learn. And in cases where there's no built-in validation API, then what do you do? </p> <p> The beauty and practicality of applicative validation is that it's <em>universal</em>. Since it's based on mathematical foundations, it's not tied to a particular framework, platform, or language. These concepts exist independently of technology. Once you understand the concepts, they're always there for you. </p> <p> The code example from the previous article, as well as here, build upon the code base that accompanies <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. An example code base has to be written in <em>some</em> language, and I chose C# because I'm more familiar with it than I am with <a href="https://www.java.com/">Java</a>, <a href="https://isocpp.org/">C++</a>, or <a href="https://www.typescriptlang.org/">TypeScript</a>. While I wanted the code base to be realistic, I tried hard to include only coding techniques and patterns that you could use in more than one language. </p> <p> As I wrote the book, I ran into many interesting problems and solutions that were specific to C# and ASP.NET. While I found them too specific to include in the book, I wrote <a href="/2021/06/14/new-book-code-that-fits-in-your-head">a series of blog posts</a> about them. This article is now becoming one of those. </p> <p> The point about the previous article on <a href="/2022/07/25/an-applicative-reservation-validation-example-in-c">applicative reservation validation in C#</a> was to demonstrate how the general technique works. Not specifically in ASP.NET, or even C#, but in general. </p> <p> It just so happens that this example is situated in a context where an alternative solution presents itself. This is not always the case. Sometimes you have to solve this problem yourself, and when this happens, it's useful to know that <a href="/2020/12/14/validation-a-solved-problem">validation is a solved problem</a>. Even so, while a universal solution exists, it doesn't follow that the universal solution is the best. Perhaps there are specialised solutions that are better, each within their constrained contexts. </p> <p> Perhaps ASP.NET validation is an example of that. </p> <h3 id="0b80f4aa36954378be9278761b2f27ba"> Email validation <a href="#0b80f4aa36954378be9278761b2f27ba" title="permalink">#</a> </h3> <p> The following is a report on my experience refactoring validation to use the built-in ASP.NET validation API. </p> <p> I decided to start with the <code>Email</code> property, since the only requirement is that this value should be present. That seemed like an easy way to get started. </p> <p> I added the <a href="https://docs.microsoft.com/dotnet/api/system.componentmodel.dataannotations.requiredattribute">[Required]</a> attribute to the <code>ReservationDto</code> class' <code>Email</code> property. Since this code base also uses <a href="https://docs.microsoft.com/dotnet/csharp/nullable-references">nullable reference types</a>, it was necessary to also annotate the property with the <a href="https://docs.microsoft.com/dotnet/api/system.diagnostics.codeanalysis.notnullattribute">[NotNull]</a> attribute: </p> <p> <pre>[Required,&nbsp;NotNull] <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;}</pre> </p> <p> That's not too difficult, and seems to be working satisfactorily: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 > content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-11-21&nbsp;19:00&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 } HTTP/1.1 400 Bad Request Content-Type: application/problem+json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;type&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;https://tools.ietf.org/html/rfc7231#section-6.5.1&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;title&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;One&nbsp;or&nbsp;more&nbsp;validation&nbsp;errors&nbsp;occurred.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;status&quot;</span>:&nbsp;400, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;traceId&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;|552ab5ff-494e1d1a9d4c6355.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;errors&quot;</span>:&nbsp;{&nbsp;<span style="color:#2e75b6;">&quot;Email&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;Email&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;]&nbsp;} }</pre> </p> <p> As discussed above, the response body is formatted differently than in the applicative validation example, but I consider that inconsequential for the reasons I gave. </p> <p> So far, so good. </p> <h3 id="a10d6da09d064a96bc0022e9657b62e5"> Quantity validation <a href="#a10d6da09d064a96bc0022e9657b62e5" title="permalink">#</a> </h3> <p> The next property I decided to migrate was <code>Quantity</code>. This must be a natural number; that is, an integer greater than zero. </p> <p> Disappointingly, no such built-in validation attribute seems to exist. One <a href="https://stackoverflow.com/a/7419330/126014">highly voted Stack Overflow answer</a> suggested using the <a href="https://docs.microsoft.com/dotnet/api/system.componentmodel.dataannotations.rangeattribute">[Range]</a> attribute, so I tried that: </p> <p> <pre>[Range(1,&nbsp;<span style="color:blue;">int</span>.MaxValue,&nbsp;ErrorMessage&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Quantity&nbsp;must&nbsp;be&nbsp;a&nbsp;natural&nbsp;number.&quot;</span>)] <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> As a <em>declarative</em> approach to validation goes, I don't think this is off to a good start. I like declarative programming, but I'd prefer to be able to declare that <code>Quantity</code> must be a <em>natural number</em>, rather than in the range of <code>1</code> and <code>int.MaxValue</code>. </p> <p> Does it work, though? </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-11-21&nbsp;19:00&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;0 } HTTP/1.1 400 Bad Request Content-Type: application/problem+json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;type&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;https://tools.ietf.org/html/rfc7231#section-6.5.1&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;title&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;One&nbsp;or&nbsp;more&nbsp;validation&nbsp;errors&nbsp;occurred.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;status&quot;</span>:&nbsp;400, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;traceId&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;|d9a6be38-4be82ede7c525913.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;errors&quot;</span>:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Email&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;Email&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Quantity&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;Quantity&nbsp;must&nbsp;be&nbsp;a&nbsp;natural&nbsp;number.&quot;</span>&nbsp;] &nbsp;&nbsp;} }</pre> </p> <p> While it does capture the intent that <code>Quantity</code> must be one or greater, it fails to echo back the offending value. </p> <p> In order to address that concern, I tried reading the documentation to find a way forward. Instead I found this: </p> <blockquote> <p> "Internally, the attributes call <a href="https://docs.microsoft.com/en-us/dotnet/api/system.string.format">String.Format</a> with a placeholder for the field name and sometimes additional placeholders. [...]" </p> <p> "To find out which parameters are passed to <code>String.Format</code> for a particular attribute's error message, see the <a href="https://github.com/dotnet/runtime/tree/main/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations">DataAnnotations source code</a>." </p> <footer><cite><a href="https://docs.microsoft.com/aspnet/core/mvc/models/validation">ASP.NET validation documentation</a></cite></footer> </blockquote> <p> Really?! </p> <p> If you have to read implementation code, <a href="/encapsulation-and-solid">encapsulation</a> is broken. </p> <p> Hardly impressed, I nonetheless found <a href="https://github.com/dotnet/runtime/blob/main/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RangeAttribute.cs">the RangeAttribute source code</a>. Alas, it only passes the property <code>name</code>, <code>Minimum</code>, and <code>Maximum</code> to <code>string.Format</code>, but not the offending value: </p> <p> <pre>return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, Minimum, Maximum);</pre> </p> <p> This looked like a dead end, but at least it's possible to extend the ASP.NET validation API: </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;">NaturalNumberAttribute</span>&nbsp;:&nbsp;ValidationAttribute { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">protected</span>&nbsp;<span style="color:blue;">override</span>&nbsp;ValidationResult&nbsp;IsValid( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">object</span>&nbsp;value, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValidationContext&nbsp;validationContext) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(validationContext&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:blue;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(validationContext)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;i&nbsp;=&nbsp;value&nbsp;<span style="color:blue;">as</span>&nbsp;<span style="color:blue;">int</span>?; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(i.HasValue&nbsp;&amp;&amp;&nbsp;0&nbsp;&lt;&nbsp;i) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;ValidationResult.Success; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ValidationResult( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;</span>{validationContext.MemberName}<span style="color:#a31515;">&nbsp;must&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer,&nbsp;but&nbsp;was:&nbsp;</span>{value}<span style="color:#a31515;">.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Adding this <code>NaturalNumberAttribute</code> class enabled me to change the annotation of the <code>Quantity</code> property: </p> <p> <pre>[NaturalNumber] <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 seems to get the job done: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-11-21&nbsp;19:00&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;0 } HTTP/1.1 400 Bad Request Content-Type: application/problem+json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;type&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;https://tools.ietf.org/html/rfc7231#section-6.5.1&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;title&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;One&nbsp;or&nbsp;more&nbsp;validation&nbsp;errors&nbsp;occurred.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;status&quot;</span>:&nbsp;400, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;traceId&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;|bb45b60d-4bd255194871157d.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;errors&quot;</span>:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Email&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;Email&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Quantity&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;Quantity&nbsp;must&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer,&nbsp;but&nbsp;was:&nbsp;0.&quot;</span>&nbsp;] &nbsp;&nbsp;} }</pre> </p> <p> The <code>[NaturalNumber]</code> attribute now correctly reports the offending value together with a useful error message. </p> <p> Compare, however, the above <code>NaturalNumberAttribute</code> class to the <code>TryParseQuantity</code> function, repeated here for convenience: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;Validated&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#74531f;">TryParseQuantity</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Quantity&nbsp;&lt;&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Validated.Fail&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;Quantity&nbsp;must&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer,&nbsp;but&nbsp;was:&nbsp;</span>{Quantity}<span style="color:#a31515;">.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Validated.Succeed&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;(Quantity); }</pre> </p> <p> <code>TryParseQuantity</code> is shorter and has half the <a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a> of <code>NaturalNumberAttribute</code>. In isolation, at least, I'd prefer the shorter, simpler alternative. </p> <h3 id="3c90c9ded0af42fd9017593c9a387e97"> Date and time validation <a href="#3c90c9ded0af42fd9017593c9a387e97" title="permalink">#</a> </h3> <p> Remaining is validation of the <code>At</code> property. As a first step, I converted the property to a <code>DateTime</code> value and added attributes: </p> <p> <pre>[Required,&nbsp;NotNull] <span style="color:blue;">public</span>&nbsp;DateTime?&nbsp;At&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;}</pre> </p> <p> I'd been a little apprehensive doing that, fearing that it'd break a lot of code (particularly tests), but that turned out not to be the case. In fact, it actually simplified a few of the tests. </p> <p> On the other hand, this doesn't really work as required: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-11-21&nbsp;19:00&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;0 } HTTP/1.1 400 Bad Request Content-Type: application/problem+json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;type&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;https://tools.ietf.org/html/rfc7231#section-6.5.1&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;title&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;One&nbsp;or&nbsp;more&nbsp;validation&nbsp;errors&nbsp;occurred.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;status&quot;</span>:&nbsp;400, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;traceId&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;|1e1d600e-4098fb36635642f6.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;errors&quot;</span>:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;dto&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;dto&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;$.at&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;JSON&nbsp;value&nbsp;could&nbsp;not&nbsp;be&nbsp;converted&nbsp;to&nbsp;System.Nullable`1[System.DateTime].↩ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Path:&nbsp;$.at&nbsp;|&nbsp;LineNumber:&nbsp;0&nbsp;|&nbsp;BytePositionInLine:&nbsp;26.&quot;</span>&nbsp;] &nbsp;&nbsp;} }</pre> </p> <p> (I've wrapped the last error message over two lines for readability. The <code>↩</code> symbol indicates where I've wrapped the text.) </p> <p> There are several problems with this response. First, in addition to complaining about the missing <code>at</code> property, it should also have reported that there are problems with the <code>Quantity</code> and that the <code>Email</code> property is missing. Instead, the response implies that the <code>dto</code> field is missing. That's likely confusing to client developers, because <code>dto</code> is an implementation detail; it's the name of the C# parameter of the method that handles the request. Client developers can't and shouldn't know this. Instead, it looks as though the REST API somehow failed to receive the JSON document that the client posted. </p> <p> Second, the error message exposes other implementation details, here that the <code>at</code> field has the type <code>System.Nullable`1[System.DateTime]</code>. This is, at best, irrelevant. At worst, it could be a security issue, because it reveals to a would-be attacker that the system is implemented on .NET. </p> <p> Third, the framework rejects what looks like a perfectly good date and time: <code>2022-11-21 19:00</code>. This is a breaking change, since the API used to accept such values. </p> <p> What's wrong with <code>2022-11-21 19:00</code>? It's not a valid <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> string. According to the ISO 8601 standard, the date and time must be separated by <code>T</code>: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-11-21T19:00&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;0 } HTTP/1.1 400 Bad Request Content-Type: application/problem+json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;type&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;https://tools.ietf.org/html/rfc7231#section-6.5.1&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;title&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;One&nbsp;or&nbsp;more&nbsp;validation&nbsp;errors&nbsp;occurred.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;status&quot;</span>:&nbsp;400, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;traceId&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;|1e1d600f-4098fb36635642f6.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;errors&quot;</span>:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Email&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;Email&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Quantity&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;Quantity&nbsp;must&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer,&nbsp;but&nbsp;was:&nbsp;0.&quot;</span>&nbsp;] &nbsp;&nbsp;} }</pre> </p> <p> Posting a valid ISO 8601 string does, indeed, enable the client to proceed - only to receive a new set of error messages. After I converted <code>At</code> to <code>DateTime?</code>, the ASP.NET validation framework fails to collect and report all errors. Instead it stops if it can't parse the <code>At</code> property. It doesn't report any other errors that might also be present. </p> <p> That is exactly the requirement that applicative validation so elegantly solves. </p> <h3 id="e9986e66f63c476ca529788afaa863e4"> Tolerant Reader <a href="#e9986e66f63c476ca529788afaa863e4" title="permalink">#</a> </h3> <p> While it's true that <code>2022-11-21 19:00</code> isn't valid ISO 8601, it's unambiguous. According to <a href="https://en.wikipedia.org/wiki/Robustness_principle">Postel's law</a> an API should be a <a href="https://martinfowler.com/bliki/TolerantReader.html">Tolerant Reader</a>. It's not. </p> <p> This problem, however, is solvable. First, add the Tolerant Reader: </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;">DateTimeConverter</span>&nbsp;:&nbsp;JsonConverter&lt;DateTime&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;DateTime&nbsp;Read( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">ref</span>&nbsp;Utf8JsonReader&nbsp;reader, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;typeToConvert, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JsonSerializerOptions&nbsp;options) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;DateTime.Parse( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.GetString(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CultureInfo.InvariantCulture); &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;">void</span>&nbsp;Write( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Utf8JsonWriter&nbsp;writer, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;value, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JsonSerializerOptions&nbsp;options) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(writer&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:blue;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(writer)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteStringValue(value.ToString(<span style="color:#a31515;">&quot;s&quot;</span>)); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Then add it to the JSON serialiser's <a href="https://docs.microsoft.com/dotnet/api/system.text.json.jsonserializeroptions.converters">Converters</a>: </p> <p> <pre>opts.JsonSerializerOptions.Converters.Add(<span style="color:blue;">new</span>&nbsp;DateTimeConverter());</pre> </p> <p> This, at least, addresses the Tolerant Reader concern: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-11-21&nbsp;19:00&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;0 } HTTP/1.1 400 Bad Request Content-Type: application/problem+json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;type&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;https://tools.ietf.org/html/rfc7231#section-6.5.1&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;title&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;One&nbsp;or&nbsp;more&nbsp;validation&nbsp;errors&nbsp;occurred.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;status&quot;</span>:&nbsp;400, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;traceId&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;|11576943-400dafd4b489c282.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;errors&quot;</span>:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Email&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;Email&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Quantity&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;Quantity&nbsp;must&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer,&nbsp;but&nbsp;was:&nbsp;0.&quot;</span>&nbsp;] &nbsp;&nbsp;} }</pre> </p> <p> The API now accepts the slightly malformed <code>at</code> field. It also correctly handles if the field is entirely missing: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;0 } HTTP/1.1 400 Bad Request Content-Type: application/problem+json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;type&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;https://tools.ietf.org/html/rfc7231#section-6.5.1&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;title&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;One&nbsp;or&nbsp;more&nbsp;validation&nbsp;errors&nbsp;occurred.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;status&quot;</span>:&nbsp;400, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;traceId&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;|11576944-400dafd4b489c282.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;errors&quot;</span>:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;At&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;At&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Email&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;Email&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;Quantity&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;Quantity&nbsp;must&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer,&nbsp;but&nbsp;was:&nbsp;0.&quot;</span>&nbsp;] &nbsp;&nbsp;} }</pre> </p> <p> On the other hand, it <em>still</em> doesn't gracefully handle the case when the <code>at</code> field is unrecoverably malformed: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 content-type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;0 } HTTP/1.1 400 Bad Request Content-Type: application/problem+json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;type&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;https://tools.ietf.org/html/rfc7231#section-6.5.1&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;title&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;One&nbsp;or&nbsp;more&nbsp;validation&nbsp;errors&nbsp;occurred.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;status&quot;</span>:&nbsp;400, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;traceId&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;|11576945-400dafd4b489c282.&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;errors&quot;</span>:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;supplied&nbsp;value&nbsp;is&nbsp;invalid.&quot;</span>&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;dto&quot;</span>:&nbsp;[&nbsp;<span style="color:#a31515;">&quot;The&nbsp;dto&nbsp;field&nbsp;is&nbsp;required.&quot;</span>&nbsp;] &nbsp;&nbsp;} }</pre> </p> <p> <code>The supplied value is invalid.</code> and <code>The dto field is required.</code>? That's not really helpful. And what happened to <code>The Email field is required.</code> and <code>Quantity must be a positive integer, but was: 0.</code>? </p> <p> If there's a way to address this problem, I don't know how. I've tried adding another custom attribute, similar to the above <code>NaturalNumberAttribute</code> class, but that doesn't solve it - probably because the model binder (that deserialises the JSON document to a <code>ReservationDto</code> instance) runs before the validation. </p> <p> Perhaps there's a way to address this problem with yet another class that derives from a base class, but I think that I've already played enough <a href="https://en.wikipedia.org/wiki/Whac-A-Mole">Whack-a-mole</a> to arrive at a conclusion. </p> <h3 id="fc3e2119ed1c4a7a8cff0c0992a8b071"> Conclusion <a href="#fc3e2119ed1c4a7a8cff0c0992a8b071" title="permalink">#</a> </h3> <p> Your context may differ from mine, so the conclusion that I arrive at may not apply in your situation. For example, I'm given to understand that one benefit that the ASP.NET validation framework provides is that when used with ASP.NET MVC (instead of as a Web API), (some of) the validation logic can also run in <a href="https://www.javascript.com/">JavaScript</a> in browsers. This, ostensibly, reduces code duplication. </p> <blockquote> <p> "Yet in the case of validation, a Declarative model is far superior to a FP one. The declarative model allows various environments to implement validation as they need it (IE: Client side validation) while the FP one is strictly limited to the environment executing the code." </p> <footer><cite><a href="https://twitter.com/PopCatalin/status/1551478926005911553">PopCatalin</a></cite></footer> </blockquote> <p> On the other hand, using the ASP.NET validation framework requires more code, and more complex code, than with applicative validation. It's a particular set of APIs that you have to learn, and that knowledge doesn't transfer to other frameworks, platforms, or languages. </p> <p> Apart from client-side validation, I fail to see how applicative validation <em>"re implement[s validation] more poorly, by renouncing standardization, interoperability and globalization"</em>. </p> <p> I'm not aware that there's any <em>standard</em> for validation as such, so I think that @PopCatalin has the 'standard' ASP.NET validation API in mind. If so, I consider applicative validation a much more standardised solution than a specialised API. </p> <p> If by <em>interoperability</em> @PopCatalin means the transfer of logic from server side to client side, then it's true that the applicative validation I showed in the previous article runs exclusively on the server. I wonder, however, how much of such custom validation as <code>NaturalNumberAttribute</code> automatically transfers to the client side. </p> <p> When it comes to globalisation, I fail to see how applicative validation is less globalisable than the ASP.NET validation framework. One could easily replace the hard-coded strings in my examples with resource strings. </p> <p> It would seem, again, that <a href="https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule">any sufficiently complicated custom validation framework contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of applicative validation</a>. </p> <blockquote> <p> "I must admit I really liked the declarative OOP model using annotations when I first saw it in Java (EJB3.0, almost 20yrs ago) until I saw FP way of doing things. FP way is so much simpler and powerful, because it's just function composition, nothing more, no hidden "magic"." </p> <footer><cite><a href="https://twitter.com/witoldsz/status/1552429555503493120">Witold Szczerba</a></cite></footer> </blockquote> <p> I still find myself in the same camp as Witold Szczerba. It's easy to get started using validation annotations, but it doesn't follow that it's simpler or better in the long run. As <a href="https://en.wikipedia.org/wiki/Rich_Hickey">Rich Hickey</a> points out in <a href="https://www.infoq.com/presentations/Simple-Made-Easy/">Simple Made Easy</a>, <em>simple</em> and <em>easy</em> isn't the same. If I have to maintain code, I'll usually choose the simple solution over the easy solution. That means choosing applicative validation over a framework-specific validation API. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="f6deac18851d47c3b066f82a8be3847d"> <div class="comment-author">Maurice Johnson</div> <div class="comment-content"> <p> Hello Mark. I was just wondering, is it possible to use the type system to do the validation instead ? </p> <p> What I mean is, for example, to make all the ReservationDto's field a type with validation in the constructor (like a class name, a class email, and so on). Normally, when the framework will build ReservationDto, it will try to construct the fields using the type constructor, and if there is an explicit error thrown during the construction, the framework will send us back the error with the provided message. </p> <p> Plus, I think types like "email", "name" and "at" are reusable. And I feel like we have more possibilities for validation with that way of doing than with the validation attributes. </p> <p> What do you think ? </p> <p> Regards. </p> </div> <div class="comment-date">2022-08-16 08:30 UTC</div> </div> <div class="comment" id="89a9ef6d57f645d7a1e848aaf20b8b72"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Maurice, thank you for writing. I started writing a reply, but it grew, so I'm going to turn it into a blog post. I'll post an update here once I've published it, but expect it to take a few weeks. </p> </div> <div class="comment-date">2022-08-18 7:50 UTC</div> </div> <div class="comment" id="e932eb2fd0804a049314872d5fe6a358"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> I've published the article: <a href="/2022/08/22/can-types-replace-validation">Can types replace validation?</a>. </p> </div> <div class="comment-date">2022-08-22 6:00 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>. Endomorphism as an invariant functor https://blog.ploeh.dk/2022/08/08/endomorphism-as-an-invariant-functor 2022-08-08T04:43:00+00:00 Mark Seemann <div id="post"> <p> <em>An article (also) for object-oriented programmers.</em> </p> <p> This article is part of <a href="/2022/08/01/invariant-functors">a series of articles about invariant functors</a>. An invariant functor is a <a href="/2018/03/22/functors">functor</a> that is neither covariant nor contravariant. See the series introduction for more details. </p> <p> An <a href="https://en.wikipedia.org/wiki/Endomorphism">endomorphism</a> is a function where the return type is the same as the input type. </p> <p> In <a href="https://www.haskell.org/">Haskell</a> we denote an endomorphism as <code>a -&gt; a</code>, in <a href="http://fsharp.org/">F#</a> we have to add an apostrophe: <code>'a -&gt; 'a</code>, while in C# such a function corresponds to the delegate <code>Func&lt;T, T&gt;</code> or, alternatively, to a method that has the same return type as input type. </p> <p> In Haskell you can treat an endomorphism like a <a href="/2017/10/06/monoids">monoid</a> by wrapping it in a <a href="https://bartoszmilewski.com/2014/01/14/functors-are-containers">container</a> called <a href="https://hackage.haskell.org/package/base/docs/Data-Monoid.html#t:Endo">Endo</a>: <code>Endo a</code>. In C#, we <a href="/2021/05/31/from-state-tennis-to-endomorphism">might model it as an interface</a> called <code><span style="color:#2b91af;">IEndomorphism</span>&lt;<span style="color:#2b91af;">T</span>&gt;</code>. </p> <p> That looks enough like a functor that you might wonder if it is one, but it turns out that it's neither co- nor contravariant. You can deduce this with positional variance analysis (which I've learned from <a href="https://thinkingwithtypes.com/">Thinking with Types</a>). In short, this is because <code>T</code> appears as both input and output - it's neither co- nor contravariant, but rather <em>invariant</em>. </p> <h3 id="39fa705060f143aba4c18dd2c8ff7f2d"> Explicit endomorphism interface in C# <a href="#39fa705060f143aba4c18dd2c8ff7f2d" title="permalink">#</a> </h3> <p> Consider an <code><span style="color:#2b91af;">IEndomorphism</span>&lt;<span style="color:#2b91af;">T</span>&gt;</code> interface in C#: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IEndomorphism</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">Run</span>(T&nbsp;<span style="color:#1f377f;">x</span>); }</pre> </p> <p> I've borrowed this interface from the article <a href="/2021/05/31/from-state-tennis-to-endomorphism">From State tennis to endomorphism</a>. In that article I explain that I only introduce this interface for educational reasons. I don't expect you to use something like this in production code bases. On the other hand, everything that applies to <code><span style="color:#2b91af;">IEndomorphism</span>&lt;<span style="color:#2b91af;">T</span>&gt;</code> also applies to 'naked' functions, as you'll see later in the article. </p> <p> As outlined in the introduction, you can make a container an invariant functor by implementing a non-standard version of <code>Select</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEndomorphism&lt;B&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">B</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IEndomorphism&lt;A&gt;&nbsp;<span style="color:#1f377f;">endomorphism</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">aToB</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;B,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">bToA</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;SelectEndomorphism&lt;A,&nbsp;B&gt;(endomorphism,&nbsp;aToB,&nbsp;bToA); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">SelectEndomorphism</span>&lt;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">B</span>&gt;&nbsp;:&nbsp;IEndomorphism&lt;B&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IEndomorphism&lt;A&gt;&nbsp;endomorphism; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;A,&nbsp;B&gt;&nbsp;aToB; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;B,&nbsp;A&gt;&nbsp;bToA; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">SelectEndomorphism</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;A&gt;&nbsp;<span style="color:#1f377f;">endomorphism</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">aToB</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;B,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">bToA</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.endomorphism&nbsp;=&nbsp;endomorphism; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.aToB&nbsp;=&nbsp;aToB; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.bToA&nbsp;=&nbsp;bToA; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;B&nbsp;<span style="color:#74531f;">Run</span>(B&nbsp;<span style="color:#1f377f;">x</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;aToB(endomorphism.Run(bToA(x))); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Since the <code>Select</code> method has to return an <code>IEndomorphism&lt;B&gt;</code> implementation, one option is to use a private, nested class. Most of this is <a href="/2019/12/16/zone-of-ceremony">ceremony</a> required because it's working with interfaces. The interesting part is the nested class' <code>Run</code> implementation. </p> <p> In order to translate an <code>IEndomorphism&lt;A&gt;</code> to an <code>IEndomorphism&lt;B&gt;</code>, the <code>Run</code> method first uses <code>bToA</code> to translate <code>x</code> to an <code>A</code> value. Once it has the <code>A</code> value, it can <code>Run</code> the <code>endomorphism</code>, which returns another <code>A</code> value. Finally, the method can use <code>aToB</code> to convert the returned <code>A</code> value to a <code>B</code> value that it can return. </p> <p> Here's a simple example. Imagine that you have an endomorphism 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;">Incrementer</span>&nbsp;:&nbsp;IEndomorphism&lt;BigInteger&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;BigInteger&nbsp;<span style="color:#74531f;">Run</span>(BigInteger&nbsp;<span style="color:#1f377f;">x</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;x&nbsp;+&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This one simply increments a <a href="https://docs.microsoft.com/dotnet/api/system.numerics.biginteger">BigInteger</a> value. Since <code>BigInteger</code> is isomorphic to a byte array, it's possible to transform this <code>BigInteger</code> endomorphism to a byte array endomorphism: </p> <p> <pre>[Theory] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">byte</span>[0],&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">byte</span>[]&nbsp;{&nbsp;1&nbsp;})] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">byte</span>[]&nbsp;{&nbsp;1&nbsp;},&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">byte</span>[]&nbsp;{&nbsp;2&nbsp;})] [InlineData(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">byte</span>[]&nbsp;{&nbsp;255,&nbsp;0&nbsp;},&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">byte</span>[]&nbsp;{&nbsp;0,&nbsp;1&nbsp;})] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">InvariantSelection</span>(<span style="color:blue;">byte</span>[]&nbsp;<span style="color:#1f377f;">bs</span>,&nbsp;<span style="color:blue;">byte</span>[]&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;BigInteger&gt;&nbsp;<span style="color:#1f377f;">source</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Incrementer(); &nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;<span style="color:blue;">byte</span>[]&gt;&nbsp;<span style="color:#1f377f;">destination</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source.Select(<span style="color:#1f377f;">bi</span>&nbsp;=&gt;&nbsp;bi.ToByteArray(),&nbsp;<span style="color:#1f377f;">arr</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;BigInteger(arr)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;destination.Run(bs)); }</pre> </p> <p> You can convert a <code>BigInteger</code> to a byte array with the <code>ToByteArray</code> method, and convert such a byte array back to a <code>BigInteger</code> using one of its constructor overloads. Since this is possible, the example test can convert this <code>IEndomorphism&lt;BigInteger&gt;</code> to an <code>IEndomorphism&lt;<span style="color:blue;">byte</span>[]&gt;</code> and later <code>Run</code> it. </p> <h3 id="f9afa75c0b014df68d29ddf1244f329f"> Mapping functions in F# <a href="#f9afa75c0b014df68d29ddf1244f329f" title="permalink">#</a> </h3> <p> You don't need an interface in order to turn an endomorphism into an invariant functor. An endomorphism is just a function that has the same input and output type. In C# such a function has the type <code>Func&lt;T, T&gt;</code>, while in F# it's written <code>&#39;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;&#39;a</code>. </p> <p> You could write an F# module that defines an <code>invmap</code> function, which would be equivalent to the above <code>Select</code> method: </p> <p> <pre><span style="color:blue;">module</span>&nbsp;Endo&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;&#39;b)&nbsp;-&gt;&nbsp;(&#39;b&nbsp;-&gt;&nbsp;&#39;a)&nbsp;-&gt;&nbsp;(&#39;a&nbsp;-&gt;&nbsp;&#39;a)&nbsp;-&gt;&nbsp;(&#39;b&nbsp;-&gt;&nbsp;&#39;b)</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;invmap&nbsp;(f&nbsp;:&nbsp;&#39;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;&#39;b)&nbsp;(g&nbsp;:&nbsp;&#39;b&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;&#39;a)&nbsp;(h&nbsp;:&nbsp;&#39;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;&#39;a)&nbsp;=&nbsp;g&nbsp;&gt;&gt;&nbsp;h&nbsp;&gt;&gt;&nbsp;f</pre> </p> <p> Since this function doesn't have to deal with the ceremony of interfaces, the implementation is simple function composition: For any input, first apply it to the <code>g</code> function, then apply the output to the <code>h</code> function, and again apply the output of that function to the <code>f</code> function. </p> <p> Here's the same example as above: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;increment&nbsp;(bi&nbsp;:&nbsp;BigInteger)&nbsp;=&nbsp;bi&nbsp;+&nbsp;BigInteger.One <span style="color:green;">//&nbsp;byte&nbsp;[]&nbsp;-&gt;&nbsp;byte&nbsp;[]</span> <span style="color:blue;">let</span>&nbsp;bArrInc&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;Endo.invmap&nbsp;(<span style="color:blue;">fun</span>&nbsp;(bi&nbsp;:&nbsp;BigInteger)&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;bi.ToByteArray&nbsp;())&nbsp;BigInteger&nbsp;increment</pre> </p> <p> Here's a simple sanity check of the <code>bArrInc</code> function executed in F# Interactive: </p> <p> <pre>&gt; let bArr = bArrInc [| 255uy; 255uy; 0uy |];; val bArr : byte [] = [|0uy; 0uy; 1uy|]</pre> </p> <p> If you are wondering about that particular output value, I'll refer you to <a href="https://docs.microsoft.com/dotnet/api/system.numerics.biginteger">the BigInteger documentation</a>. </p> <h3 id="76c32ad7688b41fc9e083a51584e4a6a"> Function composition <a href="#76c32ad7688b41fc9e083a51584e4a6a" title="permalink">#</a> </h3> <p> The F# implementation of <code>invmap</code> (<code>g&nbsp;&gt;&gt;&nbsp;h&nbsp;&gt;&gt;&nbsp;f</code>) makes it apparent that an endomorphism is an invariant functor via function composition. In F#, though, that fact almost disappears in all the type declaration ceremony. In the Haskell instance from the <a href="https://hackage.haskell.org/package/invariant">invariant</a> package it's even clearer: </p> <p> <pre><span style="color:blue;">instance</span>&nbsp;<span style="color:blue;">Invariant</span>&nbsp;<span style="color:blue;">Endo</span>&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;invmap&nbsp;f&nbsp;g&nbsp;(Endo&nbsp;h)&nbsp;=&nbsp;Endo&nbsp;(f&nbsp;.&nbsp;h&nbsp;.&nbsp;g)</pre> </p> <p> Perhaps a diagram is helpful: </p> <p> <img src="/content/binary/invariant-map-diagram.png" alt="Arrow diagram showing the mapping from an endomorphism in a to an endomorphism in b."> </p> <p> If you have a function <code>h</code> from the type <code>a</code> to <code>a</code> and you need a function <code>b -&gt; b</code>, you can produce it by putting <code>g</code> in front of <code>h</code>, and <code>f</code> after. That's also what the above C# implementation does. In F#, you can express such a composition as <code>g&nbsp;&gt;&gt;&nbsp;h&nbsp;&gt;&gt;&nbsp;f</code>, which seems natural to most westerners, since it goes from left to right. In Haskell, most expressions are instead expressed from right to left, so it becomes: <code>f&nbsp;.&nbsp;h&nbsp;.&nbsp;g</code>. In any case, the result is the desired function that takes a <code>b</code> value as input and returns a <code>b</code> value as output. That composed function is indicated by a dashed arrow in the above diagram. </p> <h3 id="3934e941d51f47c698d8b803b7adb97c"> Identity law <a href="#3934e941d51f47c698d8b803b7adb97c" title="permalink">#</a> </h3> <p> Contrary to my usual habit, I'm going to <em>prove</em> that both invariant functor laws hold for this implementation. I'll use equational reasoning with <a href="https://bartoszmilewski.com/2015/01/20/functors/">the notation that Bartosz Milewski uses</a>. Here's the proof that the <code>invmap</code> instance obeys the identity law: </p> <p> <pre>&nbsp;&nbsp;invmap&nbsp;id&nbsp;id&nbsp;(Endo&nbsp;h) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;invmap&nbsp;} &nbsp;&nbsp;Endo&nbsp;(id&nbsp;.&nbsp;h&nbsp;.&nbsp;id) =&nbsp;{&nbsp;eta&nbsp;expansion&nbsp;} &nbsp;&nbsp;Endo&nbsp;(\x&nbsp;-&gt;&nbsp;(id&nbsp;.&nbsp;h&nbsp;.&nbsp;id)&nbsp;x) =&nbsp;{&nbsp;defintion&nbsp;of&nbsp;composition&nbsp;(.)&nbsp;} &nbsp;&nbsp;Endo&nbsp;(\x&nbsp;-&gt;&nbsp;id&nbsp;(h&nbsp;(id&nbsp;x))) =&nbsp;{&nbsp;defintion&nbsp;of&nbsp;id&nbsp;} &nbsp;&nbsp;Endo&nbsp;(\x&nbsp;-&gt;&nbsp;h&nbsp;x) =&nbsp;{&nbsp;eta&nbsp;reduction&nbsp;} &nbsp;&nbsp;Endo&nbsp;h =&nbsp;{&nbsp;definition&nbsp;of&nbsp;id&nbsp;} &nbsp;&nbsp;id&nbsp;(Endo&nbsp;h)</pre> </p> <p> While I'm not going to comment further on that, I can show you what the identity law looks like in C#: </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;">IdentityLaw</span>(<span style="color:blue;">long</span>&nbsp;<span style="color:#1f377f;">l</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;BigInteger&gt;&nbsp;<span style="color:#1f377f;">e</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Incrementer(); &nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;BigInteger&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;e.Select(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x,&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(e.Run(l),&nbsp;actual.Run(l)); }</pre> </p> <p> In C#, you typically write the identity function (<code>id</code> in F# and Haskell) as the lambda expression <code><span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x</code>, since the identity function isn't 'built in' for C# like it is for F# and Haskell. (You can define it yourself, but it's not as <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a>.) </p> <h3 id="e47f375aafe441949e057787a5d35178"> Composition law <a href="#e47f375aafe441949e057787a5d35178" title="permalink">#</a> </h3> <p> As with the identity law, I'll start by suggesting a proof for the composition law for the Haskell instance: </p> <p> <pre>&nbsp;&nbsp;invmap&nbsp;f2&nbsp;f2&#39;&nbsp;$&nbsp;invmap&nbsp;f1&nbsp;f1&#39;&nbsp;(Endo&nbsp;h) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;invmap&nbsp;} &nbsp;&nbsp;invmap&nbsp;f2&nbsp;f2&#39;&nbsp;$&nbsp;Endo&nbsp;(f1&nbsp;.&nbsp;h&nbsp;.&nbsp;f1&#39;) =&nbsp;{&nbsp;defintion&nbsp;of&nbsp;($)&nbsp;} &nbsp;&nbsp;invmap&nbsp;f2&nbsp;f2&#39;&nbsp;(Endo&nbsp;(f1&nbsp;.&nbsp;h&nbsp;.&nbsp;f1&#39;)) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;invmap&nbsp;} &nbsp;&nbsp;Endo&nbsp;(f2&nbsp;.&nbsp;(f1&nbsp;.&nbsp;h&nbsp;.&nbsp;f1&#39;)&nbsp;.&nbsp;f2&#39;) =&nbsp;{&nbsp;associativity&nbsp;of&nbsp;composition&nbsp;(.)&nbsp;} &nbsp;&nbsp;Endo&nbsp;((f2&nbsp;.&nbsp;f1)&nbsp;.&nbsp;h&nbsp;.&nbsp;(f1&#39;&nbsp;.&nbsp;f2&#39;)) =&nbsp;{&nbsp;definition&nbsp;of&nbsp;invmap&nbsp;} &nbsp;&nbsp;invmap&nbsp;(f2&nbsp;.&nbsp;f1)&nbsp;(f1&#39;&nbsp;.&nbsp;f2&#39;)&nbsp;(Endo&nbsp;h)</pre> </p> <p> As above, a C# example may also help. First, assume that you have some endomorphism 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;">SecondIncrementer</span>&nbsp;:&nbsp;IEndomorphism&lt;TimeSpan&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;TimeSpan&nbsp;<span style="color:#74531f;">Run</span>(TimeSpan&nbsp;<span style="color:#1f377f;">x</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;x&nbsp;+&nbsp;TimeSpan.FromSeconds(1); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> A test then demonstrates the composition law in action: </p> <p> <pre>[Theory] [InlineData(-3)] [InlineData(0)] [InlineData(11)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">CompositionLaw</span>(<span style="color:blue;">long</span>&nbsp;<span style="color:#1f377f;">x</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;SecondIncrementer(); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TimeSpan,&nbsp;<span style="color:blue;">long</span>&gt;&nbsp;<span style="color:#1f377f;">f1</span>&nbsp;=&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;ts.Ticks; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">long</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">f1p</span>&nbsp;=&nbsp;<span style="color:#1f377f;">l</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;TimeSpan(l); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">long</span>,&nbsp;IntPtr&gt;&nbsp;<span style="color:#1f377f;">f2</span>&nbsp;=&nbsp;<span style="color:#1f377f;">l</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;IntPtr(l); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;IntPtr,&nbsp;<span style="color:blue;">long</span>&gt;&nbsp;<span style="color:#1f377f;">f2p</span>&nbsp;=&nbsp;<span style="color:#1f377f;">ip</span>&nbsp;=&gt;&nbsp;ip.ToInt64(); &nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;IntPtr&gt;&nbsp;<span style="color:#1f377f;">left</span>&nbsp;=&nbsp;i.Select(f1,&nbsp;f1p).Select(f2,&nbsp;f2p); &nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;IntPtr&gt;&nbsp;<span style="color:#1f377f;">right</span>&nbsp;=&nbsp;i.Select(<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;f2(f1(ts)),&nbsp;<span style="color:#1f377f;">ip</span>&nbsp;=&gt;&nbsp;f1p(f2p(ip))); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(left.Run(<span style="color:blue;">new</span>&nbsp;IntPtr(x)),&nbsp;right.Run(<span style="color:blue;">new</span>&nbsp;IntPtr(x))); }</pre> </p> <p> Don't try to make any sense of this. As outlined in the introductory article, in order to use an invariant functor, you're going to need an isomorphism. In order to demonstrate the composition law, you need <em>three</em> types that are isomorphic. Since you can convert back and forth between <code>TimeSpan</code> and <code>IntPtr</code> via <code>long</code>, this requirement is formally fulfilled. It doesn't make any sense to add a second to a value and then turn it into a function that changes a pointer. It sounds more like a security problem waiting to happen... Don't try this at home, kids. </p> <h3 id="ac1e8d3a75b54f9691c616755750ff77"> Conclusion <a href="#ac1e8d3a75b54f9691c616755750ff77" title="permalink">#</a> </h3> <p> Since an endomorphism can be modelled as a 'generic type', it may look like a candidate for a functor or <a href="/2021/09/02/contravariant-functors">contravariant functor</a>, but alas, neither is possible. The best we can get (apart from <a href="/2017/11/13/endomorphism-monoid">a monoid instance</a>) is an invariant functor. </p> <p> The invariant functor instance for an endomorphism turns out to be simple function composition. That's not how all invariant functors, work, though. </p> <p> <strong>Next:</strong> <a href="/2022/08/29/natural-transformations-as-invariant-functors">Natural transformations as invariant functors</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>. Invariant functors https://blog.ploeh.dk/2022/08/01/invariant-functors 2022-08-01T05:49:00+00:00 Mark Seemann <div id="post"> <p> <em>Containers that support mapping isomorphic values.</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>. So far, you've seen examples of both co- and <a href="/2021/09/02/contravariant-functors">contravariant functors</a>, including <a href="/2021/11/01/profunctors">profunctors</a>. You've also seen a few examples of <a href="/2020/10/19/monomorphic-functors">monomorphic functors</a> - mappable containers where there's no variance at all. </p> <p> What happens, on the other hand, if you have a container of (generic) values, but it's neither co- nor contravariant? An <a href="https://en.wikipedia.org/wiki/Endomorphism">endomorphism</a> is an example - it's neither co- nor contravariant. You'll see a treatment of that in a later article. </p> <p> Even if neither co- nor contravariant mappings exists for a container, all may not be lost. It may still be an <em>invariant functor</em>. </p> <h3 id="40d4c4a6deed4af593b3cf002563f085"> Invariance <a href="#40d4c4a6deed4af593b3cf002563f085" title="permalink">#</a> </h3> <p> Consider a <a href="https://bartoszmilewski.com/2014/01/14/functors-are-containers">container</a> <code>f</code> (for <em>functor</em>). Depending on its variance, we call it <em>covariant</em>, <em>contravariant</em>, or <em>invariant</em>: </p> <ul> <li><em>Covariance</em> means that any function <code>a -&gt; b</code> can be lifted into a function <code>f a -&gt; f b</code>.</li> <li><em>Contravariance</em> means that any function <code>a -&gt; b</code> can be lifted into a function <code>f b -&gt; f a</code>.</li> <li><em>Invariance</em> means that in general, no function <code>a -&gt; b</code> can be lifted into a function over <code>f a</code>.</li> </ul> <p> <em>In general</em>, that is. A limited escape hatch exists: </p> <blockquote> <p> "an invariant type [...] allows you to map from <code>a</code> to <code>b</code> if and only if <code>a</code> and <code>b</code> are isomorphic. In a very real sense, this isn't an interesting property - an isomorphism between <code>a</code> and <code>b</code> means they're already the same thing to begin with." </p> <footer><cite>Sandy Maguire, <a href="https://thinkingwithtypes.com/">Thinking with Types</a></cite></footer> </blockquote> <p> In <a href="https://www.haskell.org/">Haskell</a> we may define an invariant functor (AKA <a href="http://comonad.com/reader/2008/rotten-bananas/">exponential functor</a>) as in the <a href="https://hackage.haskell.org/package/invariant">invariant</a> package: </p> <p> <pre><span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Invariant</span>&nbsp;f&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;<span style="color:#2b91af;">invmap</span>&nbsp;::&nbsp;(a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;b)&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;(b&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;a)&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;f&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;f&nbsp;b</pre> </p> <p> This means that an <em>invariant functor</em> <code>f</code> is a container of values where a translation from <code>f a</code> to <code>f b</code> exists if it's possible to translate contained values both ways: From <code>a</code> to <code>b</code>, and from <code>b</code> to <code>a</code>. Callers of the <code>invmap</code> function must supply translations that go both ways. </p> <h3 id="36e114d8871c46c9addb2e38936a2872"> Invariant functor in C# <a href="#36e114d8871c46c9addb2e38936a2872" title="permalink">#</a> </h3> <p> It's possible to translate the concept to a language like C#. Since C# doesn't have higher-kinded types, we have to examine the abstraction as a set of patterns or templates. For <a href="/2018/03/22/functors">functors</a> and <a href="/2022/03/28/monads">monads</a>, the C# compiler can perform 'compile-time duck typing' to recognise these motifs to enable query syntax. For more advanced or exotic universal abstractions, such as <a href="/2018/12/24/bifunctors">bifunctors</a>, <a href="/2021/11/01/profunctors">profunctors</a>, or invariant functors, we have to use a concrete container type as a stand-in for 'any' functor. In this article, I'll call it <code><span style="color:#2b91af;">Invariant</span>&lt;<span style="color:#2b91af;">A</span>&gt;</code>. </p> <p> Such a generic class must have a mapping function that corresponds to the above <code>invmap</code>. In C# it has this signature: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Invariant&lt;B&gt;&nbsp;<span style="color:#74531f;">InvMap</span>&lt;<span style="color:#2b91af;">B</span>&gt;(Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">aToB</span>,&nbsp;Func&lt;B,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">bToA</span>)</pre> </p> <p> In this example, <code>InvMap</code> is an instance method on <code><span style="color:#2b91af;">Invariant</span>&lt;<span style="color:#2b91af;">A</span>&gt;</code>. You may use it like this: </p> <p> <pre>Invariant&lt;<span style="color:blue;">long</span>&gt;&nbsp;<span style="color:#1f377f;">il</span>&nbsp;=&nbsp;createInvariant(); Invariant&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">its</span>&nbsp;=&nbsp;il.InvMap(<span style="color:#1f377f;">l</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;TimeSpan(l),&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;ts.Ticks);</pre> </p> <p> It's not that easy to find good examples of truly isomorphic primitives, but <a href="https://docs.microsoft.com/dotnet/api/system.timespan">TimeSpan</a> is just a useful wrapper of <code>long</code>, so it's possible to translate back and forth without loss of information. To create a <code>TimeSpan</code> from a <code>long</code>, you can use the suitable constructor overload. To get a <code>long</code> from a <code>TimeSpan</code>, you can read the <a href="https://docs.microsoft.com/dotnet/api/system.timespan.ticks">Ticks</a> property. </p> <p> Perhaps you find a method name like <code>InvMap</code> non-idiomatic in C#. Perhaps a more <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a> name might be <code>Select</code>? That's not a problem: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Invariant&lt;B&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">B</span>&gt;(Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">aToB</span>,&nbsp;Func&lt;B,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">bToA</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;InvMap(aToB,&nbsp;bToA); }</pre> </p> <p> In that case, usage would look like this: </p> <p> <pre>Invariant&lt;<span style="color:blue;">long</span>&gt;&nbsp;<span style="color:#1f377f;">il</span>&nbsp;=&nbsp;createInvariant(); Invariant&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">its</span>&nbsp;=&nbsp;il.Select(<span style="color:#1f377f;">l</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;TimeSpan(l),&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;ts.Ticks);</pre> </p> <p> In this article, I'll use <code>Select</code> in order to be consistent with C# naming conventions. Using that name, however, will not make query syntax light up. While the name is fine, the signature is not one that the C# compiler will recognise as enabling special syntax. The name does, however, suggest a kinship with a normal functor, where the mapping in C# is called <code>Select</code>. </p> <h3 id="4a5c0a55258d4e398931d2880df059fb"> Laws <a href="#4a5c0a55258d4e398931d2880df059fb" title="permalink">#</a> </h3> <p> As is usual with these kinds of universal abstractions, an invariant functor must satisfy a few laws. </p> <p> The first one we might call the <em>identity law:</em> </p> <p> <pre>invmap id id = id</pre> </p> <p> This law corresponds to the first functor law. When performing the mapping operation, if the values in the invariant functor are mapped to themselves, the result will be an unmodified functor. </p> <p> In C# such a mapping might look like this: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;i.Select(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x,&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x);</pre> </p> <p> The law then says that <code>actual</code> should be equal to <code>i</code>. </p> <p> The second law we might call the <em>composition law:</em> </p> <p> <pre>invmap f2 f2' . invmap f1 f1' = invmap (f2 . f1) (f1' . f2')</pre> </p> <p> Granted, this looks more complicated, but also directly corresponds to the second functor law. If two sequential mapping operations are performed one after the other, the result should be the same as a single mapping operation where the functions are composed. </p> <p> In C# the left-hand side might look like this: </p> <p> <pre>Invariant&lt;IntPtr&gt;&nbsp;<span style="color:#1f377f;">left</span>&nbsp;=&nbsp;i.Select(f1,&nbsp;f1p).Select(f2,&nbsp;f2p);</pre> </p> <p> In C# you can't name functions or variables with a quotation mark (like the Haskell code's <code>f1'</code> and <code>f2'</code>), so instead I named them <code>f1p</code> and <code>f2p</code> (with a <em>p</em> for <em>prime</em>). </p> <p> Likewise, the right-hand side might look like this: </p> <p> <pre>Invariant&lt;IntPtr&gt;&nbsp;<span style="color:#1f377f;">right</span>&nbsp;=&nbsp;i.Select(<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;f2(f1(ts)),&nbsp;<span style="color:#1f377f;">ip</span>&nbsp;=&gt;&nbsp;f1p(f2p(ip)));</pre> </p> <p> The composition law says that the <code>left</code> and <code>right</code> values must be equal. </p> <p> You'll see some more detailed examples in later articles. </p> <h3 id="14c58dc57f9744dfbc955015d03b871e"> Examples <a href="#14c58dc57f9744dfbc955015d03b871e" title="permalink">#</a> </h3> <p> This is all too abstract to seem useful in itself, so example are warranted. You'll be able to peruse examples of specific invariant functors in separate articles: </p> <ul> <li><a href="/2022/08/08/endomorphism-as-an-invariant-functor">Endomorphism as an invariant functor</a></li> <li><a href="/2022/08/29/natural-transformations-as-invariant-functors">Natural transformations as invariant functors</a></li> <li>Functors as invariant functors</li> <li>Contravariant functors as invariant functors</li> </ul> <p> As two of the titles suggest, all functors are also invariant functors, and the same goes for contravariant functors: </p> <p> <img src="/content/binary/invariant-functor-set-diagram.png" alt="Set diagram. The biggest set labelled invariant functos contains two other sets labelled functors and invariant functors."> </p> <p> To be honest, invariant functors are exotic, and you are unlikely to need them in all but the rarest cases. Still, I <em>did</em> run into a scenario where I needed an invariant functor instance to be able to perform <a href="/2022/09/05/the-state-pattern-and-the-state-monad">a particular sleight of hand</a>. The rabbit holes we sometimes fall into... </p> <h3 id="ffa0e597f09c40e7bcd1cabe808aa0d5"> Conclusion <a href="#ffa0e597f09c40e7bcd1cabe808aa0d5" title="permalink">#</a> </h3> <p> Invariant functors form a set that contains both co- and contravariant functors, as well as some data structures that are neither. This is an exotic abstraction that you may never need. It did, however, get me out of a bind at one time. </p> <strong>Next:</strong> <a href="/2022/08/08/endomorphism-as-an-invariant-functor">Endomorphism as an invariant functor</a>. </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="faae4a8cbe294be8ac7596488d675483"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <blockquote> For <a href="/2018/03/22/functors">functors</a> and <a href="/2022/03/28/monads">monads</a>, the C# compiler can perform 'compile-time duck typing' to recognise these motifs to enable query syntax. </blockquote> <p> Instead of 'compile-time duck typing', I think a better phrase to describe this is <a href="https://en.wikipedia.org/wiki/Structural_type_system">structural typing</a>. </p> </div> <div class="comment-date">2022-09-17 16:20 UTC</div> </div> <div class="comment" id="98be00b677484b11a51d8e583c25baa5"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tyson, thank you for writing. I wasn't aware of the term <em>structural typing</em>, so thank you for the link. I've now read that Wikipedia article, but all I know is what's there. Based on it, though, it looks as though <a href="https://fsharp.org">F#</a>'s <a href="https://learn.microsoft.com/dotnet/fsharp/language-reference/generics/statically-resolved-type-parameters">Statically Resolved Type Parameters</a> are another example of structural typing, in addition to the <a href="https://ocaml.org/">OCaml</a> example given in the article. </p> <p> IIRC, <a href="https://www.purescript.org/">PureScript</a>'s <em>row polymorphism</em> may be another example, but it's been many years since <a href="/2017/06/06/fractal-trees-with-purescript">I played with it</a>. In other words, I could be mistaken. </p> <p> Based on the Wikipedia article, it looks as though structural typing is more concerned with polymorphism, but granted, so is duck typing. Given how wrong 'compile-time duck typing' actually is in the above context, 'structural typing' seems more correct. </p> <p> I may still stick with 'compile-time duck typing' as a loose metaphor, though, because most people know what duck typing is, whereas I'm not sure as many people know of structural typing. The purpose of the metaphor is, after all, to be helpful. </p> </div> <div class="comment-date">2022-09-19 14:46 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>. An applicative reservation validation example in C# https://blog.ploeh.dk/2022/07/25/an-applicative-reservation-validation-example-in-c 2022-07-25T06:56:00+00:00 Mark Seemann <div id="post"> <p> <em>How to return all relevant error messages in a composable way.</em> </p> <p> I've previously suggested that <a href="/2020/12/14/validation-a-solved-problem">I consider validation a solved problem</a>. I still do, until someone disproves me with a counterexample. Here's a fairly straightforward <a href="/2018/11/05/applicative-validation">applicative validation</a> example in C#. </p> <p> After corresponding and speaking with readers of <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> I've learned that some readers have objections to the following lines of code: </p> <p> <pre>Reservation?&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;=&nbsp;dto.Validate(id); <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;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;BadRequestResult();</pre> </p> <p> This code snippet demonstrates how to <a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/">parse, not validate</a>, an incoming Data Transfer Object (DTO). This code base uses C#'s <a href="https://docs.microsoft.com/dotnet/csharp/nullable-references">nullable reference types</a> feature to distinguish between null and non-null objects. Other languages (and earlier versions of C#) can instead use <a href="/2022/04/25/the-maybe-monad">the Maybe monad</a>. Nothing in this article or the book hinges on the <em>nullable reference types</em> feature. </p> <p> If the <code>Validate</code> method (which I really should have called <code>TryParse</code> instead) returns a null value, the Controller from which this code snippet is taken returns a <code>400 Bad Request</code> response. </p> <p> The <code>Validate</code> method is an instance method on the DTO class: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;Reservation?&nbsp;<span style="color:#74531f;">Validate</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!DateTime.TryParse(At,&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;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Email&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;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Quantity&nbsp;&lt;&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">null</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d, &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); }</pre> </p> <p> What irks some readers is the loss of information. While <code>Validate</code> 'knows' why it's rejecting a candidate, that information is lost and no error message is communicated to unfortunate HTTP clients. </p> <p> One email from a reader went on about this for quite some time and I got the impression that the sender considered this such a grave flaw that it invalidates the entire book. </p> <p> That's not the case. </p> <h3 id="26803ee560dd42be825ec266694d0211"> Rabbit hole, evaded <a href="#26803ee560dd42be825ec266694d0211" title="permalink">#</a> </h3> <p> When I wrote the code like above, I was fully aware of trade-offs and priorities. I understood that this particular design would mean that clients get no information about <em>why</em> a particular reservation JSON document is rejected - only that it is. </p> <p> This was a simplification that I explicitly decided to make for educational reasons. </p> <p> The above design is based on something as simple as a null check. I expect all my readers to be able to follow that code. As hinted above, you could also model a method like <code>Validate</code> with the Maybe monad, but while Maybe preserves success cases, it throws away all information about errors. In a production system, this is rarely acceptable, but I found it acceptable for the example code in the book, since this isn't the main topic. </p> <p> Instead of basing the design on nullable reference types or the Maybe monad, you can instead base parsing on applicative validation. In order to explain that, I'd first need to explain <a href="/2018/03/22/functors">functors</a>, <a href="/2018/10/01/applicative-functors">applicative functors</a>, and applicative validation. It might also prove helpful to the reader to explain <a href="/2018/05/22/church-encoding">Church encodings</a>, <a href="/2018/12/24/bifunctors">bifunctors</a>, and <a href="/2017/11/27/semigroups">semigroups</a>. That's quite a rabbit hole to fall into, and I felt that it would be such a big digression from the themes of the book that I decided not to go there. </p> <p> On this blog, however, I have all the space and time I'd like. I can digress as much as I'd like. Most of that digression has already happened. Those articles are already on the blog. I'm going to assume that you've read all of the articles I just linked, or that you understand these concepts. </p> <p> In this article, I'm going to rewrite the DTO parser to also return error messages. It's an entirely local change that breaks no existing tests. </p> <h3 id="5f6a7326fb484c1d8b4402b24e49d13b"> Validated <a href="#5f6a7326fb484c1d8b4402b24e49d13b" title="permalink">#</a> </h3> <p> Most functional programmers are already aware of the <a href="/2022/05/09/an-either-monad">Either monad</a>. They often reach for it when they need to expand the Maybe monad with <a href="https://fsharpforfunandprofit.com/posts/recipe-part2/">an error track</a>. </p> <p> The problem with the Either monad is, however, that it short-circuits error handling. It's like throwing exceptions. As soon as an Either composition hits the first error, it stops processing the rest of the data. As a caller, you only get one error message, even if there's more than one thing wrong with your input value. </p> <p> In a distributed system where a client posts a document to a service, you'd like to respond with a collection of errors. </p> <p> You can do this with a data type that's isomorphic with Either, but behaves differently as an applicative functor. Instead of short-circuiting on the first error, it collects them. This, however, turns out to be incompatible to the Either monad's short-circuiting behaviour, so this data structure is usually not given monadic features. </p> <p> This data type is usually called <code>Validation</code>, but when I translated that to C# various static code analysis rules lit up, claiming that there was already a referenced namespace called <code>Validation</code>. Instead, I decided to call the type <code><span style="color:#2b91af;">Validated</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<span style="color:#2b91af;">S</span>&gt;</code>, which I like better anyway. </p> <p> The type arguments are <code>F</code> for <em>failure</em> and <code>S</code> for <em>success</em>. I've put <code>F</code> before <code>S</code> because by convention that's how Either works. </p> <p> I'm using an encapsulated variation of a Church encoding and a series of <code>Apply</code> overloads as described in the article <a href="/2018/10/15/an-applicative-password-list">An applicative password list</a>. There's quite a bit of boilerplate, so I'll just dump the entire contents of the file here instead of tiring you with a detailed walk-through: </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;">Validated</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<span style="color:#2b91af;">S</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IValidation</span> &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">Match</span>&lt;<span style="color:#2b91af;">T</span>&gt;(Func&lt;F,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">onFailure</span>,&nbsp;Func&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">onSuccess</span>); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IValidation&nbsp;imp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">Validated</span>(IValidation&nbsp;<span style="color:#1f377f;">imp</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.imp&nbsp;=&nbsp;imp; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Validated&lt;F,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Succeed</span>(S&nbsp;<span style="color:#1f377f;">success</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;Validated&lt;F,&nbsp;S&gt;(<span style="color:blue;">new</span>&nbsp;Success(success)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Validated&lt;F,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Fail</span>(F&nbsp;<span style="color:#1f377f;">failure</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;Validated&lt;F,&nbsp;S&gt;(<span style="color:blue;">new</span>&nbsp;Failure(failure)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;<span style="color:#74531f;">Match</span>&lt;<span style="color:#2b91af;">T</span>&gt;(Func&lt;F,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">onFailure</span>,&nbsp;Func&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">onSuccess</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;imp.Match(onFailure,&nbsp;onSuccess); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Validated&lt;F1,&nbsp;S1&gt;&nbsp;<span style="color:#74531f;">SelectBoth</span>&lt;<span style="color:#2b91af;">F1</span>,&nbsp;<span style="color:#2b91af;">S1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;F,&nbsp;F1&gt;&nbsp;<span style="color:#1f377f;">selectFailure</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S,&nbsp;S1&gt;&nbsp;<span style="color:#1f377f;">selectSuccess</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&gt;&nbsp;Validated.Fail&lt;F1,&nbsp;S1&gt;(selectFailure(f)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Validated.Succeed&lt;F1,&nbsp;S1&gt;(selectSuccess(s))); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Validated&lt;F1,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">SelectFailure</span>&lt;<span style="color:#2b91af;">F1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;F,&nbsp;F1&gt;&nbsp;<span style="color:#1f377f;">selectFailure</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;SelectBoth(selectFailure,&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Validated&lt;F,&nbsp;S1&gt;&nbsp;<span style="color:#74531f;">SelectSuccess</span>&lt;<span style="color:#2b91af;">S1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S,&nbsp;S1&gt;&nbsp;<span style="color:#1f377f;">selectSuccess</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;SelectBoth(<span style="color:#1f377f;">f</span>&nbsp;=&gt;&nbsp;f,&nbsp;selectSuccess); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Validated&lt;F,&nbsp;S1&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">S1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S,&nbsp;S1&gt;&nbsp;<span style="color:#1f377f;">selector</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;SelectSuccess(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;">Success</span>&nbsp;:&nbsp;IValidation &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;S&nbsp;success; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Success</span>(S&nbsp;<span style="color:#1f377f;">success</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>.success&nbsp;=&nbsp;success; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;<span style="color:#74531f;">Match</span>&lt;<span style="color:#2b91af;">T</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;F,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">onFailure</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">onSuccess</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;onSuccess(success); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &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;">Failure</span>&nbsp;:&nbsp;IValidation &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;F&nbsp;failure; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Failure</span>(F&nbsp;<span style="color:#1f377f;">failure</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>.failure&nbsp;=&nbsp;failure; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;<span style="color:#74531f;">Match</span>&lt;<span style="color:#2b91af;">T</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;F,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">onFailure</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">onSuccess</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;onFailure(failure); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} } <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;">Validated</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Validated&lt;F,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Succeed</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<span style="color:#2b91af;">S</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S&nbsp;<span style="color:#1f377f;">success</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Validated&lt;F,&nbsp;S&gt;.Succeed(success); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Validated&lt;F,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Fail</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<span style="color:#2b91af;">S</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F&nbsp;<span style="color:#1f377f;">failure</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Validated&lt;F,&nbsp;S&gt;.Fail(failure); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Validated&lt;F,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Apply</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">S</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Validated&lt;F,&nbsp;Func&lt;T,&nbsp;S&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Validated&lt;F,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;F,&nbsp;F,&nbsp;F&gt;&nbsp;<span style="color:#1f377f;">combine</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&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;&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;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;selector.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f1</span>&nbsp;=&gt;&nbsp;source.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f2</span>&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;S&gt;(combine(f1,&nbsp;f2)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">_</span>&nbsp;&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;S&gt;(f1)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">map</span>&nbsp;=&gt;&nbsp;source.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f2</span>&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;S&gt;(f2), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">x</span>&nbsp;&nbsp;=&gt;&nbsp;Succeed&lt;F,&nbsp;S&gt;(map(x)))); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Validated&lt;F,&nbsp;Func&lt;T2,&nbsp;S&gt;&gt;&nbsp;<span style="color:#74531f;">Apply</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<span style="color:#2b91af;">T1</span>,&nbsp;<span style="color:#2b91af;">T2</span>,&nbsp;<span style="color:#2b91af;">S</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Validated&lt;F,&nbsp;Func&lt;T1,&nbsp;T2,&nbsp;S&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Validated&lt;F,&nbsp;T1&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;F,&nbsp;F,&nbsp;F&gt;&nbsp;<span style="color:#1f377f;">combine</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&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;&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;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;selector.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f1</span>&nbsp;=&gt;&nbsp;source.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f2</span>&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;Func&lt;T2,&nbsp;S&gt;&gt;(combine(f1,&nbsp;f2)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">_</span>&nbsp;&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;Func&lt;T2,&nbsp;S&gt;&gt;(f1)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">map</span>&nbsp;=&gt;&nbsp;source.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f2</span>&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;Func&lt;T2,&nbsp;S&gt;&gt;(f2), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">x</span>&nbsp;&nbsp;=&gt;&nbsp;Succeed&lt;F,&nbsp;Func&lt;T2,&nbsp;S&gt;&gt;(<span style="color:#1f377f;">y</span>&nbsp;=&gt;&nbsp;map(x,&nbsp;y)))); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Validated&lt;F,&nbsp;Func&lt;T2,&nbsp;T3,&nbsp;S&gt;&gt;&nbsp;<span style="color:#74531f;">Apply</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<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;">S</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Validated&lt;F,&nbsp;Func&lt;T1,&nbsp;T2,&nbsp;T3,&nbsp;S&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Validated&lt;F,&nbsp;T1&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;F,&nbsp;F,&nbsp;F&gt;&nbsp;<span style="color:#1f377f;">combine</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&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;&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;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;selector.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f1</span>&nbsp;=&gt;&nbsp;source.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f2</span>&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;Func&lt;T2,&nbsp;T3,&nbsp;S&gt;&gt;(combine(f1,&nbsp;f2)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">_</span>&nbsp;&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;Func&lt;T2,&nbsp;T3,&nbsp;S&gt;&gt;(f1)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">map</span>&nbsp;=&gt;&nbsp;source.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">f2</span>&nbsp;=&gt;&nbsp;Fail&lt;F,&nbsp;Func&lt;T2,&nbsp;T3,&nbsp;S&gt;&gt;(f2), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">x</span>&nbsp;&nbsp;=&gt;&nbsp;Succeed&lt;F,&nbsp;Func&lt;T2,&nbsp;T3,&nbsp;S&gt;&gt;((<span style="color:#1f377f;">y</span>,&nbsp;<span style="color:#1f377f;">z</span>)&nbsp;=&gt;&nbsp;map(x,&nbsp;y,&nbsp;z)))); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Validated&lt;F,&nbsp;Func&lt;T2,&nbsp;T3,&nbsp;S&gt;&gt;&nbsp;<span style="color:#74531f;">Apply</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<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;">S</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;Func&lt;T1,&nbsp;T2,&nbsp;T3,&nbsp;S&gt;&nbsp;<span style="color:#1f377f;">map</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Validated&lt;F,&nbsp;T1&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;F,&nbsp;F,&nbsp;F&gt;&nbsp;<span style="color:#1f377f;">combine</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Apply( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Succeed&lt;F,&nbsp;Func&lt;T1,&nbsp;T2,&nbsp;T3,&nbsp;S&gt;&gt;((<span style="color:#1f377f;">x</span>,&nbsp;<span style="color:#1f377f;">y</span>,&nbsp;<span style="color:#1f377f;">z</span>)&nbsp;=&gt;&nbsp;map(x,&nbsp;y,&nbsp;z)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;combine); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> I only added the <code>Apply</code> overloads that I needed for the following demo code. As stated above, I'm not going to launch into a detailed walk-through, since the code follows the concepts lined out in the various articles I've already mentioned. If there's something that you'd like me to explain then please <a href="https://github.com/ploeh/ploeh.github.com#comments">leave a comment</a>. </p> <p> Notice that <code><span style="color:#2b91af;">Validated</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<span style="color:#2b91af;">S</span>&gt;</code> has no <code>SelectMany</code> method. It's deliberately not a <a href="/2022/03/28/monads">monad</a>, because monadic <em>bind</em> (<code>SelectMany</code>) would conflict with the applicative functor implementation. </p> <h3 id="533e728019834b22b323ffab10f4cae8"> Individual parsers <a href="#533e728019834b22b323ffab10f4cae8" title="permalink">#</a> </h3> <p> An essential quality of applicative validation is that it's composable. This means that you can compose a larger, more complex parser from smaller ones. Parsing a <code><span style="color:#2b91af;">ReservationDto</span></code> object, for example, involves parsing the date and time of the reservation, the email address, and the quantity. Here's how to parse the date and time: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;Validated&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#74531f;">TryParseAt</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!DateTime.TryParse(At,&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;Validated.Fail&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;(<span style="color:#a31515;">$&quot;Invalid&nbsp;date&nbsp;or&nbsp;time:&nbsp;</span>{At}<span style="color:#a31515;">.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Validated.Succeed&lt;<span style="color:blue;">string</span>,&nbsp;DateTime&gt;(d); }</pre> </p> <p> In order to keep things simple I'm going to use strings for error messages. You could instead decide to encode error conditions as a <a href="https://en.wikipedia.org/wiki/Tagged_union">sum type</a> or other polymorphic type. This would be appropriate if you also need to be able to make programmatic decisions based on individual error conditions, or if you need to translate the error messages to more than one language. </p> <p> The <code><span style="color:#74531f;">TryParseAt</span></code> function only attempts to parse the <code>At</code> property to a <code>DateTime</code> value. If parsing fails, it returns a <code><span style="color:#2b91af;">Failure</span></code> value with a helpful error message; otherwise, it wraps the parsed date and time in a <code><span style="color:#2b91af;">Success</span></code> value. </p> <p> Parsing the email address is similar: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;Validated&lt;<span style="color:blue;">string</span>,&nbsp;Email&gt;&nbsp;<span style="color:#74531f;">TryParseEmail</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Email&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;">return</span>&nbsp;Validated.Fail&lt;<span style="color:blue;">string</span>,&nbsp;Email&gt;(<span style="color:#a31515;">$&quot;Email&nbsp;address&nbsp;is&nbsp;missing.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Validated.Succeed&lt;<span style="color:blue;">string</span>,&nbsp;Email&gt;(<span style="color:blue;">new</span>&nbsp;Email(Email)); }</pre> </p> <p> As is parsing the quantity: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;Validated&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#74531f;">TryParseQuantity</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Quantity&nbsp;&lt;&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Validated.Fail&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">$&quot;Quantity&nbsp;must&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer,&nbsp;but&nbsp;was:&nbsp;</span>{Quantity}<span style="color:#a31515;">.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Validated.Succeed&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;(Quantity); }</pre> </p> <p> There's no reason to create a parser for the reservation name, because if the name doesn't exist, instead use the empty string. That operation can't fail. </p> <h3 id="48f0650702f1490392838bf3c5c88cd1"> Composition <a href="#48f0650702f1490392838bf3c5c88cd1" title="permalink">#</a> </h3> <p> You can now use applicative composition to reuse those individual parsers in a more complex parser: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;Validated&lt;<span style="color:blue;">string</span>,&nbsp;Reservation&gt;&nbsp;<span style="color:#74531f;">TryParse</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;DateTime,&nbsp;Email,&nbsp;<span style="color:blue;">int</span>,&nbsp;Reservation&gt;&nbsp;<span style="color:#1f377f;">createReservation</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:#1f377f;">at</span>,&nbsp;<span style="color:#1f377f;">email</span>,&nbsp;<span style="color:#1f377f;">quantity</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation(id,&nbsp;at,&nbsp;email,&nbsp;<span style="color:blue;">new</span>&nbsp;Name(Name&nbsp;??&nbsp;<span style="color:#a31515;">&quot;&quot;</span>),&nbsp;quantity); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">combine</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:#1f377f;">x</span>,&nbsp;<span style="color:#1f377f;">y</span>)&nbsp;=&gt;&nbsp;<span style="color:blue;">string</span>.Join(Environment.NewLine,&nbsp;x,&nbsp;y); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;createReservation &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Apply(TryParseAt(),&nbsp;combine) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Apply(TryParseEmail(),&nbsp;combine) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Apply(TryParseQuantity(),&nbsp;combine); }</pre> </p> <p> <code><span style="color:#1f377f;">createReservation</span></code> is a local function that closes over <code>id</code> and <code>Name</code>. Specifically, it uses the null coalescing operator (<code>??</code>) to turn a null name into the empty string. On the other hand, it takes <code>at</code>, <code>email</code>, and <code>quantity</code> as inputs, since these are the values that must first be parsed. </p> <p> A type like <code><span style="color:#2b91af;">Validated</span>&lt;<span style="color:#2b91af;">F</span>,&nbsp;<span style="color:#2b91af;">S</span>&gt;</code> is only an applicative functor when the failure dimension (<code>F</code>) gives rise to a semigroup. The way I've modelled it here is as a binary operation that you need to pass as a parameter to each <code>Apply</code> overload. This seems awkward, but is good enough for a proof of concept. </p> <p> The <code><span style="color:#1f377f;">combine</span></code> function joins two strings together, separated by a line break. </p> <p> The <code><span style="color:#74531f;">TryParse</span></code> function composes <code><span style="color:#1f377f;">createReservation</span></code> with <code>TryParseAt</code>, <code>TryParseEmail</code>, and <code>TryParseQuantity</code> using the various <code>Apply</code> overloads. The combination is a <code>Validated</code> value that's either a failure string or a properly encapsulated <code>Reservation</code> object. </p> <h3 id="04091776345e4f4b8ba4d446d8d80376"> Using the parser <a href="#04091776345e4f4b8ba4d446d8d80376" title="permalink">#</a> </h3> <p> Client code can now invoke the <code>TryParse</code> function on the DTO. Here is the code inside the <code><span style="color:#74531f;">Post</span></code> method on the <code><span style="color:#2b91af;">ReservationsController</span></code> class: </p> <p> <pre>[HttpPost(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/reservations&quot;</span>)] <span style="color:blue;">public</span>&nbsp;Task&lt;ActionResult&gt;&nbsp;<span style="color:#74531f;">Post</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;ReservationDto&nbsp;<span style="color:#1f377f;">dto</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(dto&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(dto)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">id</span>&nbsp;=&nbsp;dto.ParseId()&nbsp;??&nbsp;Guid.NewGuid(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">parseResult</span>&nbsp;=&nbsp;dto.TryParse(id); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;parseResult.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">msgs</span>&nbsp;=&gt;&nbsp;Task.FromResult&lt;ActionResult&gt;(<span style="color:blue;">new</span>&nbsp;BadRequestObjectResult(msgs)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;=&gt;&nbsp;TryCreate(restaurantId,&nbsp;reservation)); }</pre> </p> <p> When the <code>parseResult</code> matches a failure, it returns a <code><span style="color:blue;">new</span>&nbsp;BadRequestObjectResult</code> with all collected error messages. When, on the other hand, it matches a success, it invokes the <code><span style="color:#74531f;">TryCreate</span></code> helper method with the parsed <code>reservation</code>. </p> <h3 id="d260c38d1dd444e291868e377732fd24"> HTTP request and response <a href="#d260c38d1dd444e291868e377732fd24" title="permalink">#</a> </h3> <p> A client will now receive all relevant error messages if it posts a malformed reservation: </p> <p> <pre>POST /restaurants/1/reservations?sig=1WiLlS5705bfsffPzaFYLwntrS4FCjE5CLdaeYTHxxg%3D HTTP/1.1 Content-Type: application/json {&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;large&quot;</span>,&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Kerry&nbsp;Onn&quot;</span>,&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;-1&nbsp;} HTTP/1.1 400 Bad Request Invalid date or time: large. Email address is missing. Quantity must be a positive integer, but was: -1.</pre> </p> <p> Of course, if only a single element is wrong, only that error message will appear. </p> <h3 id="fada4ef8e64648b5a2d90e47082acfde"> Conclusion <a href="#fada4ef8e64648b5a2d90e47082acfde" title="permalink">#</a> </h3> <p> The changes described in this article were entirely local to the two involved types: <code><span style="color:#2b91af;">ReservationsController</span></code> and <code><span style="color:#2b91af;">ReservationDto</span></code>. Once I'd expanded <code><span style="color:#2b91af;">ReservationDto</span></code> with the <code><span style="color:#74531f;">TryParse</span></code> function and its helper functions, and changed <code><span style="color:#2b91af;">ReservationsController</span></code> accordingly, the rest of the code base compiled and all tests passed. The point is that this isn't a big change, and that's why I believe that the original design (returning null or non-null) doesn't invalidate anything else I had to say in the book. </p> <p> The change did, however, take quite a bit of boilerplate code, as witnessed by the <code>Validated</code> code dump. That API is, on the other hand, completely reusable, and you can find packages on the internet that already implement this functionality. It's not much of a burden in terms of extra code, but it would have taken a couple of extra chapters to explain in the book. It could easily have been double the size if I had to include material about functors, applicative functors, semigroups, Church encoding, etcetera. </p> <p> To fix two lines of code, I didn't think that was warranted. After all, it's not a major blocker. On the contrary, validation is a solved problem. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="22b961d6ecb84e6f8af7232b09a445fc"> <div class="comment-author">Dan Carter</div> <div class="comment-content"> <blockquote>you can find packages on the internet that already implement this functionality</blockquote> <p> Do you have any recommendations for a library that implements the <code>Validated<F, S></code> type? </p> </div> <div class="comment-date">2022-08-15 11:15 UTC</div> </div> <div class="comment" id="03273eecd6e749188106e8caef68d82e"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Dan, thank you for writing. The following is not a recommendation, but the most comprehensive C# library for functional programming currently seems to be <a href="https://github.com/louthy/language-ext">LanguageExt</a>, which includes a <a href="https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Value%20Monads/Validation/index.html">Validation</a> functor. </p> <p> I'm neither recommending nor arguing against LanguageExt. </p> <ul> <li>I've never used it in a real-world code base.</li> <li>I've been answering questions about it on <a href="https://stackoverflow.com">Stack Overflow</a>. In general, it seems to stump C# developers, since it's very Haskellish and quite advanced.</li> <li>Today is just a point in time. Libraries come and go.</li> </ul> <p> Since all the ideas presented in these articles are universal abstractions, you can safely and easily implement them yourself, instead of taking a dependency on a third-party library. If you stick with lawful implementations, the only variation possible is with naming. Do you call a functor like this one <code>Validation</code>, <code>Validated</code>, or something else? Do you call monadic <em>bind</em> <code>SelectMany</code> or <code>Bind</code>? Will you have a <code>Flatten</code> or a <code>Join</code> function? </p> <p> When working with teams that are new to these things, I usually start by adding these concepts as source code as they become useful. If a type like <code>Maybe</code> or <code>Validated</code> starts to proliferate, sooner or later you'll need to move it to a shared library so that multiple in-house libraries can use the type to communicate results across library boundaries. Eventually, you may decide to move such a dependency to a NuGet package. You can, at such time, decide to use an existing library instead of your own. </p> <p> The maintenance burden for these kinds of libraries is low, since the APIs and behaviour are defined and locked in advance by mathematics. </p> </div> <div class="comment-date">2022-08-16 5:54 UTC</div> </div> <div class="comment" id="fa7fc6662aee4889bcc9f84bc5db1b39"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <blockquote> If you stick with lawful implementations, the only variation possible is with naming. </blockquote> <p> There are also language-specific choices that can vary. </p> <p> One example involves applicative functors in C#. The "standard" API for applicative functors works well in <a href="https://blog.ploeh.dk/2018/10/01/applicative-functors/#6173a96aedaa4e97ad868c159e6d06fa">Haskell</a> and <a href="https://blog.ploeh.dk/2018/10/01/applicative-functors/#6f9b2f13951e475d8c4fc9682ad96a94">F#</a> because it is designed to be used with curried functions, and both of those languages curry their functions by default. In contrast, <a href="https://blog.ploeh.dk/2018/10/01/applicative-functors/#cef395ee19644f30bfd1ad7a84b6f912:~:text=Applicative%20functors%20push%20the%20limits%20of%20what%20you%20can%20express%20in%20C%23">applicative functors push the limits of what you can express in C#</a>. I am impressed with <a href="https://github.com/louthy/language-ext/blob/ba16d97d4909067222c8b134a80bfd6b7e54c424/LanguageExt.Tests/ValidationTests.cs#L277">the design that Language Ext uses for applicative functors</a>, which is an extension method on a (value) tuple of applicative functor instances that accepts a lambda expression that is given all the "unwrapped" values "inside" the applicative functors. </p> <p> Another example involves monads in TypeScript. To avoid the <a href="https://en.wikipedia.org/wiki/Pyramid_of_doom_(programming)">Pyramid of doom</a> when performing a sequence of monadic operations, Haskell has <a href="https://en.wikibooks.org/wiki/Haskell/do_notation">do notation</a> and F# has <a href="https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions">computation expressions</a>. There is no equivalent language feature in TypeScript, but it has <a href="https://en.wikipedia.org/wiki/Row_polymorphism">row polymorphism</a>, which <a href="https://gcanti.github.io/fp-ts/guides/do-notation.html">pf-ts uses to effectively implement do notation</a>. </p> <p> A related dimension is how to approximate high-kinded types in a language that lacks them. Language Ext passes in the monad as a type parameter as well as the "lower-kinded" type parameter and then constrains the monad type parameter to implement a monad interface parametereized by the lower type parameter as well as being a struct. I find that second constraint very intersting. Since the type parameter has a struct constraint, it has a default constructor that can be used to get an instance, which then implements methods according to the interface constraint. For more infomration, see <a href="https://github.com/louthy/language-ext/wiki/Does-C%23-Dream-Of-Electric-Monads%3F">this wiki article</a> for a gentle introduction and <a href="https://github.com/louthy/language-ext/blob/ba16d97d4909067222c8b134a80bfd6b7e54c424/LanguageExt.Core/Class%20Instances/Trans/Trans.cs#L74-L80">Trans.cs</a> for how Language Ext uses this approach to only implement traverse once. Similarly, F#+ has a feature called <a href="https://fsprojects.github.io/FSharpPlus/generic-doc.html">generic functions</a> that enable one to write F# like <code>map aFoo</code> instead of the typical <code>Foo.map aFoo</code>. </p> </div> <div class="comment-date">2022-09-20 02:00 UTC</div> </div> <div class="comment" id="5619079f7c994fc0bd0dbbdbfeec9e4a"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tyson, thank you for writing. I agree that details differ. Clearly, this is true across languages, where, say, <a href="https://www.haskell.org/">Haskell</a>'s <code>fmap</code> has a name different from C#'s <code>SelectMany</code>. To state the obvious, the syntax is also different. </p> <p> Even within the same language, you can have variations. Functor mapping in Haskell is generally called <code>fmap</code>, but you can also use <code>map</code> explicitly for lists. The same could be true in C#. I've seen functor and monad implementations in C# that use method names like <code>Map</code> and <code>Bind</code> rather than <code>Select</code> and <code>SelectMany</code>. </p> <p> To expand on this idea, one may also observe that what one language calls <em>Option</em>, another language calls <em>Maybe</em>. The same goes for <code>Result</code> versus <code>Either</code>. </p> <p> As you know, the names <code>Select</code> and <code>SelectMany</code> are special because they enable C# query syntax. While methods named <code>Map</code> and <code>Bind</code> are 'the same' functions, they don't light up that language feature. Another way to enable syntactic sugar for monads in C# is via <code>async</code> and <code>await</code>, as <a href="https://eiriktsarpalis.wordpress.com/2020/07/20/effect-programming-in-csharp/">shown by Eirik Tsarpalis and Nick Palladinos</a>. </p> <p> I do agree with you that there are various options available to an implementer. The point I was trying to make is that while implementation details differ, the concepts are the same. Thus, as a <em>user</em> of one of these APIs (monads, monoids, etc.) you only have to learn the mental model once. You still have to learn the implementation details. </p> <p> I recently heard a professor at <a href="https://en.wikipedia.org/wiki/UCPH_Department_of_Computer_Science">DIKU</a> state that once you know one programming language, you should be able to learn another one in a week. That's the same general idea. </p> <p> (I do, however, have issues with that statement about programming languages as a universal assertion, but I agree that it tends to hold for mainstream languages. When I read <a href="/ref/mazes-for-programmers">Mazes for Programmers</a> I'd never programmed in <a href="https://www.ruby-lang.org/en/">Ruby</a> before, but I had little trouble picking it up for the exercises. On the other hand, most people don't learn Haskell in a week.) </p> </div> <div class="comment-date">2022-09-20 17:42 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>. Natural transformations https://blog.ploeh.dk/2022/07/18/natural-transformations 2022-07-18T08:12:00+00:00 Mark Seemann <div id="post"> <p> <em>Mappings between functors, with some examples in C#.</em> </p> <p> This article is part of <a href="/2022/07/11/functor-relationships">a series of articles about functor relationships</a>. In this one you'll learn about natural transformations, which are simply mappings between two <a href="/2018/03/22/functors">functors</a>. It's probably the easiest relationship to understand. In fact, it may be so obvious that your reaction is: <em>Is that it?</em> </p> <p> In programming, a natural transformation is just a function from one functor to another. A common example is a function that tries to extract a value from a collection. You'll see specific examples a little later in this article. </p> <h3 id="05a07e6563da4ba39c83bd92250d3056"> Laws <a href="#05a07e6563da4ba39c83bd92250d3056" title="permalink">#</a> </h3> <p> In this, the dreaded section on <em>laws</em>, I have a nice surprise for you: There aren't any (that we need worry about)! </p> <p> In the broader context of <a href="https://en.wikipedia.org/wiki/Category_theory">category theory</a> there are, in fact, rules that a natural transformation must follow. </p> <blockquote> <p> "Haskell's parametric polymorphism has an unexpected consequence: any polymorphic function of the type: </p> <p> <pre>alpha :: F a -&gt; G a</pre> </p> <p> "where <code>F</code> and <code>G</code> are functors, automatically satisfies the naturality condition." </p> <footer><cite><a href="https://bartoszmilewski.com/2015/04/07/natural-transformations/">Natural Transformations</a>, Bartosz Milewski</cite></footer> </blockquote> <p> While C# isn't <a href="https://www.haskell.org">Haskell</a>, .NET generics are similar enough to Haskell <a href="https://en.wikipedia.org/wiki/Parametric_polymorphism">parametric polymorphism</a> that the result, as far as I can tell, carry over. (Again, however, we have to keep in mind that C# doesn't distinguish between <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a> and impure actions. The knowledge that I infer translates for pure functions. For impure actions, there are no guarantees.) </p> <p> The C# equivalent of the above <code>alpha</code> function would be a method like this: </p> <p> <pre>G&lt;T&gt;&nbsp;<span style="color:#74531f;">Alpha</span>&lt;<span style="color:#2b91af;">T</span>&gt;(F&lt;T&gt;&nbsp;<span style="color:#1f377f;">f</span>)</pre> </p> <p> where both <code>F</code> and <code>G</code> are functors. </p> <h3 id="643a53f5758f485f8a7000f9e7825c5c"> Safe head <a href="#643a53f5758f485f8a7000f9e7825c5c" title="permalink">#</a> </h3> <p> Natural transformations easily occur in normal programming. You've probably written some yourself, without being aware of it. Here are some examples. </p> <p> It's common to attempt to get the first element of a collection. Collections, however, may be empty, so this is not always possible. In Haskell, you'd model that as a function that takes a list as input and returns a <code>Maybe</code> as output: </p> <p> <pre>Prelude Data.Maybe&gt; :t listToMaybe listToMaybe :: [a] -&gt; Maybe a Prelude Data.Maybe&gt; listToMaybe [] Nothing Prelude Data.Maybe&gt; listToMaybe [7] Just 7 Prelude Data.Maybe&gt; listToMaybe [3,9] Just 3 Prelude Data.Maybe&gt; listToMaybe [5,9,2,4,4] Just 5</pre> </p> <p> In many tutorials such a function is often called <code>safeHead</code>, because it returns the <em>head</em> of a list (i.e. the first item) in a safe manner. It returns <code>Nothing</code> if the list is empty. In <a href="https://fsharp.org">F#</a> this function is called <a href="https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-seqmodule.html#tryHead">tryHead</a>. </p> <p> In C# you could write a similar function like this: </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;">TryFirst</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;IEnumerable&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(source.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;T&gt;(source.First()); &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;Maybe.Empty&lt;T&gt;(); }</pre> </p> <p> This extension method (which is really a pure function) is a natural transformation between two functors. The source functor is the <a href="/2022/04/19/the-list-monad">list functor</a> and the destination is <a href="/2018/03/26/the-maybe-functor">the Maybe functor</a>. </p> <p> Here are some unit tests that demonstrate how it works: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">TryFirstWhenEmpty</span>() { &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;Guid&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;Enumerable.Empty&lt;Guid&gt;().TryFirst(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(Maybe.Empty&lt;Guid&gt;(),&nbsp;actual); } [Theory] [InlineData(<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>&nbsp;},&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;baz&quot;</span>&nbsp;},&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;qux&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;quux&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;quuz&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;corge&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;corge&quot;</span>&nbsp;},&nbsp;<span style="color:#a31515;">&quot;qux&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">TryFirstWhenNotEmpty</span>(<span style="color:blue;">string</span>[]&nbsp;<span style="color:#1f377f;">arr</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;arr.TryFirst(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">string</span>&gt;(expected),&nbsp;actual); }</pre> </p> <p> All these tests pass. </p> <h3 id="6d899e8f2a7948ed898eaaefc3064dc6"> Safe index <a href="#6d899e8f2a7948ed898eaaefc3064dc6" title="permalink">#</a> </h3> <p> The above <em>safe head</em> natural transformation is just one example. Even for a particular combination of functors like <em>List to Maybe</em> many natural transformations may exist. For this particular combination, there are infinitely many natural transformations. </p> <p> You can view the <em>safe head</em> example as a special case of a more general set of <em>safe indexing</em>. With a collection of values, you can attempt to retrieve the value at a particular index. Since a collection can contain an arbitrary number of elements, however, there's no guarantee that there's an element at the requested index. </p> <p> In order to avoid exceptions, then, you can try to retrieve the value at an index, getting a Maybe value as a result. </p> <p> The F# <code>Seq</code> module defines a function called <a href="https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-seqmodule.html#tryItem">tryItem</a>. This function takes an index and a sequence (<code>IEnumerable&lt;T&gt;</code>) and returns an <code>option</code> (F#'s name for Maybe): </p> <p> <pre>&gt; Seq.tryItem 2 [2;5;3;5];; val it : int option = Some 3</pre> </p> <p> The <code>tryItem</code> function itself is <em>not</em> a natural transformation, but because of currying, it's a function that <em>returns</em> a natural transformation. When you partially apply it with an index, it becomes a natural transformation: <code>Seq.tryItem 3</code> is a natural transformation <code>seq&lt;'a&gt; -&gt; 'a option</code>, as is <code>Seq.tryItem 4</code>, <code>Seq.tryItem 5</code>, and so on ad infinitum. Thus, there are infinitely many natural transformations from the List functor to the Maybe functor, and <em>safe head</em> is simply <code>Seq.tryItem 0</code>. </p> <p> In C# you can use the various <code>Func</code> delegates to implement currying, but if you want something that looks a little more object-oriented, you could write code 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;">Index</span> { &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;index; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Index</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">index</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.index&nbsp;=&nbsp;index; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Maybe&lt;T&gt;&nbsp;<span style="color:#74531f;">TryItem</span>&lt;<span style="color:#2b91af;">T</span>&gt;(IEnumerable&lt;T&gt;&nbsp;<span style="color:#1f377f;">values</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">candidate</span>&nbsp;=&nbsp;values.Skip(index).Take(1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(candidate.Any()) &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;T&gt;(candidate.First()); &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;Maybe.Empty&lt;T&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This <code>Index</code> class captures an index value for potential use against any <code>IEnumerable&lt;T&gt;</code>. Thus, the <code>TryItem</code> method is a natural transformation from the List functor to the Maybe functor. Here are some examples: </p> <p> <pre>[Theory] [InlineData(0,&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">string</span>[0])] [InlineData(1,&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;bee&quot;</span>&nbsp;})] [InlineData(2,&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;nig&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;fev&quot;</span>&nbsp;})] [InlineData(4,&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;sta&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;ali&quot;</span>&nbsp;})] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">MissItem</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">i</span>,&nbsp;<span style="color:blue;">string</span>[]&nbsp;<span style="color:#1f377f;">xs</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">idx</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Index(i); &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;idx.TryItem(xs); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(Maybe.Empty&lt;<span style="color:blue;">string</span>&gt;(),&nbsp;actual); } [Theory] [InlineData(0,&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>&nbsp;},&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(1,&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;baz&quot;</span>&nbsp;},&nbsp;<span style="color:#a31515;">&quot;baz&quot;</span>)] [InlineData(1,&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;qux&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;quux&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;quuz&quot;</span>&nbsp;},&nbsp;<span style="color:#a31515;">&quot;quux&quot;</span>)] [InlineData(2,&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#a31515;">&quot;corge&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;grault&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;fred&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;garply&quot;</span>&nbsp;},&nbsp;<span style="color:#a31515;">&quot;fred&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FindItem</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">i</span>,&nbsp;<span style="color:blue;">string</span>[]&nbsp;<span style="color:#1f377f;">xs</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">idx</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Index(i); &nbsp;&nbsp;&nbsp;&nbsp;Maybe&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;idx.TryItem(xs); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;Maybe&lt;<span style="color:blue;">string</span>&gt;(expected),&nbsp;actual); }</pre> </p> <p> Since there are infinitely many integers, there are infinitely many such natural transformations. (This is strictly not true for the above code, since there's a finite number of 32-bit integers. Exercise: Is it possible to rewrite the above <code>Index</code> class to instead work with <a href="https://docs.microsoft.com/dotnet/api/system.numerics.biginteger">BigInteger</a>?) </p> <p> The Haskell <a href="https://hackage.haskell.org/package/natural-transformation">natural-transformation</a> package offers an even more explicit way to present the same example: </p> <p> <pre><span style="color:blue;">import</span>&nbsp;Control.Natural <span style="color:#2b91af;">tryItem</span>&nbsp;::&nbsp;(<span style="color:blue;">Eq</span>&nbsp;a,&nbsp;<span style="color:blue;">Num</span>&nbsp;a,&nbsp;<span style="color:blue;">Enum</span>&nbsp;a)&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;[]&nbsp;:~&gt;&nbsp;<span style="color:#2b91af;">Maybe</span> tryItem&nbsp;i&nbsp;=&nbsp;NT&nbsp;$&nbsp;<span style="color:blue;">lookup</span>&nbsp;i&nbsp;.&nbsp;<span style="color:blue;">zip</span>&nbsp;[0..]</pre> </p> <p> You can view this <code>tryItem</code> function as a function that takes a number and returns a particular natural transformation. For example you can define a value called <code>tryThird</code>, which is a natural transformation from <code>[]</code> to <code>Maybe</code>: </p> <p> <pre>λ tryThird = tryItem 2 λ :t tryThird tryThird :: [] :~&gt; Maybe</pre> </p> <p> Here are some usage examples: </p> <p> <pre>λ tryThird # [] Nothing λ tryThird # [1] Nothing λ tryThird # [2,3] Nothing λ tryThird # [4,5,6] Just 6 λ tryThird # [7,8,9,10] Just 9</pre> </p> <p> In all three languages (F#, C#, Haskell), <em>safe head</em> is really just a special case of <em>safe index</em>: <code>Seq.tryItem 0</code> in F#, <code><span style="color:blue;">new</span>&nbsp;Index(0)</code> in C#, and <code>tryItem 0</code> in Haskell. </p> <h3 id="a8e50cd940974b88b5564c2939900702"> Maybe to List <a href="#a8e50cd940974b88b5564c2939900702" title="permalink">#</a> </h3> <p> You can also move in the opposite direction: From Maybe to List. In F#, I can't find a function that translates from <code>option 'a</code> to <code>seq 'a</code> (<code>IEnumerable&lt;T&gt;</code>), but there are both <a href="https://fsharp.github.io/fsharp-core-docs/reference/fsharp-core-optionmodule.html#toArray">Option.toArray</a> and <a href="https://fsharp.github.io/fsharp-core-docs/reference/fsharp-core-optionmodule.html#toList">Option.toList</a>. I'll use <code>Option.toList</code> for a few examples: </p> <p> <pre>&gt; Option.toList (None : string option);; val it : string list = [] &gt; Option.toList (Some "foo");; val it : string list = ["foo"]</pre> </p> <p> Contrary to translating from List to Maybe, going the other way there aren't a lot of options: <code>None</code> translates to an empty list, and <code>Some</code> translates to a singleton list. </p> <p> Using <a href="/2018/06/25/visitor-as-a-sum-type">a Visitor-based</a> Maybe in C#, you can implement the natural transformation like 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;">ToList</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;IMaybe&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.Accept(<span style="color:blue;">new</span>&nbsp;ToListVisitor&lt;T&gt;()); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ToListVisitor</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;:&nbsp;IMaybeVisitor&lt;T,&nbsp;IEnumerable&lt;T&gt;&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IEnumerable&lt;T&gt;&nbsp;VisitNothing &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">get</span>&nbsp;{&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Enumerable.Empty&lt;T&gt;();&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IEnumerable&lt;T&gt;&nbsp;<span style="color:#74531f;">VisitJust</span>(T&nbsp;<span style="color:#1f377f;">just</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;{&nbsp;just&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Here are some examples: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">NothingToList</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IMaybe&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">maybe</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Nothing&lt;<span style="color:blue;">double</span>&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;maybe.ToList(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Empty(actual); } [Theory] [InlineData(-1)] [InlineData(&nbsp;0)] [InlineData(15)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">JustToList</span>(<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">d</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IMaybe&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">maybe</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Just&lt;<span style="color:blue;">double</span>&gt;(d); &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;<span style="color:blue;">double</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;maybe.ToList(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Single(actual,&nbsp;d); }</pre> </p> <p> In Haskell this natural transformation is called <a href="https://hackage.haskell.org/package/base/docs/Data-Maybe.html#v:maybeToList">maybeToList</a> - just when you think that Haskell names are always <a href="/2021/06/07/abstruse-nomenclature">abstruse</a>, you learn that some are very explicit and self-explanatory. </p> <p> If we wanted, we could use the <em>natural-transformation</em> package to demonstrate that this is, indeed, a natural transformation: </p> <p> <pre>λ :t NT maybeToList NT maybeToList :: Maybe :~&gt; []</pre> </p> <p> There would be little point in doing so, since we'd need to unwrap it again to use it. Using the function directly, on the other hand, looks like this: </p> <p> <pre>λ maybeToList Nothing [] λ maybeToList $ Just 2 [2] λ maybeToList $ Just "fon" ["fon"]</pre> </p> <p> A <code>Nothing</code> value is always translated to the empty list, and a <code>Just</code> value to a singleton list, exactly as in the other languages. </p> <p> Exercise: Is this the only possible natural transformation from Maybe to List? </p> <h3 id="5dfc02dd10514c2288721ace174c7229"> Maybe-Either relationships <a href="#5dfc02dd10514c2288721ace174c7229" title="permalink">#</a> </h3> <p> The Maybe functor is isomorphic to <a href="/2019/01/14/an-either-functor">Either</a> where the <em>left</em> (or <em>error</em>) dimension is <a href="/2018/01/15/unit-isomorphisms">unit</a>. Here are the two natural transformations in F#: </p> <p> <pre><span style="color:blue;">module</span>&nbsp;Option&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;&#39;a&nbsp;option&nbsp;-&gt;&nbsp;Result&lt;&#39;a,unit&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;toResult&nbsp;=&nbsp;<span style="color:blue;">function</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Some&nbsp;x&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;Ok&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;None&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;Error&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Result&lt;&#39;a,unit&gt;&nbsp;-&gt;&nbsp;&#39;a&nbsp;option</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;ofResult&nbsp;=&nbsp;<span style="color:blue;">function</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Ok&nbsp;x&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;Some&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Error&nbsp;()&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;None</pre> </p> <p> In F#, Maybe is called <code>option</code> and Either is called <code>Result</code>. Be aware that the F# <code>Result</code> discriminated union puts the <code>Error</code> dimension to the right of the <code>Ok</code>, which is opposite of Either, where <em>left</em> is usually used for errors, and <em>right</em> for successes (because what is correct is right). </p> <p> Here are some examples: </p> <p> <pre>&gt; Some "epi" |&gt; Option.toResult;; val it : Result&lt;string,unit&gt; = Ok "epi" &gt; Ok "epi" |&gt; Option.ofResult;; val it : string option = Some "epi"</pre> </p> <p> Notice that the natural transformation from <code>Result</code> to <code>Option</code> is only defined for <code>Result</code> values where the <code>Error</code> type is <code>unit</code>. You could also define a natural transformation from <em>any</em> <code>Result</code> to <code>option</code>: </p> <p> <pre><span style="color:green;">//&nbsp;Result&lt;&#39;a,&#39;b&gt;&nbsp;-&gt;&nbsp;&#39;a&nbsp;option</span> <span style="color:blue;">let</span>&nbsp;ignoreErrorValue&nbsp;=&nbsp;<span style="color:blue;">function</span> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Ok&nbsp;x&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;Some&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Error&nbsp;_&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;None</pre> </p> <p> That's still a natural transformation, but no longer part of an isomorphism due to the loss of information: </p> <p> <pre>&gt; (Error "Catastrophic failure" |&gt; ignoreErrorValue : int option);; val it : int option = None</pre> </p> <p> Just like above, when examining the infinitely many natural transformations from List to Maybe, we can use the Haskell <em>natural-transformation</em> package to make this more explicit: </p> <p> <pre><span style="color:#2b91af;">ignoreLeft</span>&nbsp;::&nbsp;<span style="color:#2b91af;">Either</span>&nbsp;b&nbsp;:~&gt;&nbsp;<span style="color:#2b91af;">Maybe</span> ignoreLeft&nbsp;=&nbsp;NT&nbsp;$&nbsp;either&nbsp;(<span style="color:blue;">const</span>&nbsp;Nothing)&nbsp;Just</pre> </p> <p> <code>ignoreLeft</code> is a natural transformation from the <code>Either b</code> functor to the <code>Maybe</code> functor. </p> <p> Using a Visitor-based Either implementation (refactored from <a href="/2018/06/11/church-encoded-either">Church-encoded Either</a>), you can implement an equivalent <code>IgnoreLeft</code> natural transformation in C#: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IMaybe&lt;R&gt;&nbsp;<span style="color:#74531f;">IgnoreLeft</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;R&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.Accept(<span style="color:blue;">new</span>&nbsp;IgnoreLeftVisitor&lt;L,&nbsp;R&gt;()); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">IgnoreLeftVisitor</span>&lt;<span style="color:#2b91af;">L</span>,&nbsp;<span style="color:#2b91af;">R</span>&gt;&nbsp;:&nbsp;IEitherVisitor&lt;L,&nbsp;R,&nbsp;IMaybe&lt;R&gt;&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IMaybe&lt;R&gt;&nbsp;<span style="color:#74531f;">VisitLeft</span>(L&nbsp;<span style="color:#1f377f;">left</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;Nothing&lt;R&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IMaybe&lt;R&gt;&nbsp;<span style="color:#74531f;">VisitRight</span>(R&nbsp;<span style="color:#1f377f;">right</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;Just&lt;R&gt;(right); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Here are some examples: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;OMG!&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;Catastrophic&nbsp;failure&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;Important&nbsp;information!&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IgnoreLeftOfLeft</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">msg</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">e</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Left&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;(msg); &nbsp;&nbsp;&nbsp;&nbsp;IMaybe&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;e.IgnoreLeft(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;Nothing&lt;<span style="color:blue;">int</span>&gt;(),&nbsp;actual); } [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;">IgnoreLeftOfRight</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">i</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IEither&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">e</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Right&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;(i); &nbsp;&nbsp;&nbsp;&nbsp;IMaybe&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;e.IgnoreLeft(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;Just&lt;<span style="color:blue;">int</span>&gt;(i),&nbsp;actual); }</pre> </p> <p> I'm not insisting that this natural transformation is always useful, but I've occasionally found myself in situations were it came in handy. </p> <h3 id="cc17fdc2940948978ff8bea222503965"> Natural transformations to or from Identity <a href="#cc17fdc2940948978ff8bea222503965" title="permalink">#</a> </h3> <p> Some natural transformations are a little less obvious. If you have a <code><span style="color:#2b91af;">NotEmptyCollection</span>&lt;<span style="color:#2b91af;">T</span>&gt;</code> class as shown in my article <a href="/2017/12/11/semigroups-accumulate">Semigroups accumulate</a>, you could consider the <code>Head</code> property a natural transformation. It translates a <code><span style="color:#2b91af;">NotEmptyCollection</span>&lt;<span style="color:#2b91af;">T</span>&gt;</code> object to a <code>T</code> object. </p> <p> This function also exists in Haskell, where it's simply called <a href="https://hackage.haskell.org/package/base/docs/Data-List-NonEmpty.html#v:head">head</a>. </p> <p> The input type (<code><span style="color:#2b91af;">NotEmptyCollection</span>&lt;<span style="color:#2b91af;">T</span>&gt;</code> in C#, <code>NonEmpty a</code> in Haskell) is a functor, but the return type is a 'naked' value. That doesn't look like a functor. </p> <p> True, a naked value isn't a functor, but it's isomorphic to <a href="/2018/09/03/the-identity-functor">the Identity functor</a>. In Haskell, you can make that relationship quite explicit: </p> <p> <pre><span style="color:#2b91af;">headNT</span>&nbsp;::&nbsp;<span style="color:blue;">NonEmpty</span>&nbsp;:~&gt;&nbsp;<span style="color:blue;">Identity</span> headNT&nbsp;=&nbsp;NT&nbsp;$&nbsp;Identity&nbsp;.&nbsp;NonEmpty.<span style="color:blue;">head</span></pre> </p> <p> While not particularly useful in itself, this demonstrates that it's possible to think of the <code>head</code> function as a natural transformation from <code>NonEmpty</code> to <code>Identity</code>. </p> <p> Can you go the other way, too? </p> <p> Yes, indeed. Consider <a href="/2022/03/28/monads">monadic return</a>. This is a function that takes a 'naked' value and wraps it in a particular monad (which is also, always, a functor). Again, you may consider the 'naked' value as isomorphic with the Identity functor, and thus <em>return</em> as a natural transformation: </p> <p> <pre><span style="color:#2b91af;">returnNT</span>&nbsp;::&nbsp;<span style="color:blue;">Monad</span>&nbsp;m&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;<span style="color:blue;">Identity</span>&nbsp;:~&gt;&nbsp;m returnNT&nbsp;=&nbsp;NT&nbsp;$&nbsp;<span style="color:blue;">return</span>&nbsp;.&nbsp;runIdentity</pre> </p> <p> We might even consider if a function <code>a -&gt; a</code> (in Haskell syntax) or <code>Func&lt;T, T&gt;</code> (in C# syntax) might actually be a natural transformation from Identity to Identity... (It is, but only one such function exists.) </p> <h3 id="335f008f8f65439e8253bf96968af169"> Not all natural transformations are useful <a href="#335f008f8f65439e8253bf96968af169" title="permalink">#</a> </h3> <p> Are are all functor combinations possible as natural transformations? Can you take any two functors and define one or more natural transformations? I'm not sure, but it seems clear that even if it is so, not all natural transformations are useful. </p> <p> Famously, for example, you can't <a href="/2019/02/04/how-to-get-the-value-out-of-the-monad">get the value out of</a> the <a href="/2020/06/22/the-io-functor">IO functor</a>. Thus, at first glance it seems impossible to define a natural transformation <em>from</em> <code>IO</code> to some other functor. After all, how would you implement a natural transformation from <code>IO</code> to, say, the Identity functor. That seems impossible. </p> <p> On the other hand, <em>this</em> is possible: </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;">Collapse</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;IO&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">break</span>; }</pre> </p> <p> That's a natural transformation from <code>IO&lt;T&gt;</code> to <code>IEnumerable&lt;T&gt;</code>. It's possible to ignore the input value and <em>always</em> return an empty sequence. This natural transformation collapses all values to a single return value. </p> <p> You can repeat this exercise with the Haskell <em>natural-transformation</em> package: </p> <p> <pre><span style="color:#2b91af;">collapse</span>&nbsp;::&nbsp;f&nbsp;:~&gt;&nbsp;[] collapse&nbsp;=&nbsp;NT&nbsp;$&nbsp;<span style="color:blue;">const</span>&nbsp;<span style="color:blue;">[]</span></pre> </p> <p> This one collapses <em>any</em> <a href="https://bartoszmilewski.com/2014/01/14/functors-are-containers/">container</a> <code>f</code> to a List (<code>[]</code>), including <code>IO</code>: </p> <p> <pre>λ collapse # (return 10 :: IO Integer) [] λ collapse # putStrLn "ploeh" []</pre> </p> <p> Notice that in the second example, the <code>IO</code> action is <code>putStrLn "ploeh"</code>, which ought to produce the side effect of writing to the console. This is effectively prevented - instead the <code>collapse</code> natural transformation simply produces the empty list as output. </p> <p> You can define a similar natural transformation from any functor (including <code>IO</code>) to Maybe. Try it as an exercise, in either C#, Haskell, or another language. If you want a Haskell-specific exercise, also define a natural transformation of this type: <code><span style="color:blue;">Alternative</span>&nbsp;g&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;f&nbsp;:~&gt;&nbsp;g</code>. </p> <p> These natural transformations are possible, but hardly useful. </p> <h3 id="103675f9845b4aa1b32f59a510280a53"> Conclusion <a href="#103675f9845b4aa1b32f59a510280a53" title="permalink">#</a> </h3> <p> A natural transformation is a function that translates one functor into another. Useful examples are safe or total collection indexing, including retrieving the first element from a collection. These natural transformations return a populated Maybe value if the element exists, and an empty Maybe value otherwise. </p> <p> Other examples include translating Maybe values into Either values or Lists. </p> <p> A natural transformation can easily involve loss of information. Even if you're able to retrieve the first element in a collection, the return value includes only that value, and not the rest of the collection. </p> <p> A few natural transformations may be true isomorphisms, but in general, being able to go in both directions isn't required. In degenerate cases, a natural transformation may throw away all information and map to a general empty value like the empty List or an empty Maybe value. </p> <p> <strong>Next:</strong> Traversals. </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>. Functor relationships https://blog.ploeh.dk/2022/07/11/functor-relationships 2022-07-11T08:09:00+00:00 Mark Seemann <div id="post"> <p> <em>Sometimes you need to use more than one functor together.</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="/2018/10/01/applicative-functors">applicative functors</a>. </p> <p> There are situations where you can get by with a single functor. Many languages come with list comprehensions or other features to work with collections of values (C#, for instance, has <em>language-integrated query</em>, or: LINQ). The <a href="/2022/04/19/the-list-monad">list functor (and monad)</a> gives you a comprehensive API to manipulate multiple values. Likewise, you may write some parsing (<a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate">or validation</a>) that exclusively uses the <a href="/2019/01/14/an-either-functor">Either functor</a>. </p> <p> At other times, however, you may find yourself having to juggle more than one functor at once. Perhaps you are working with Either values, but one existing API returns <a href="/2018/03/26/the-maybe-functor">Maybe</a> values instead. Or perhaps you need to deal with Either values, but you're already working within <a href="/2018/09/24/asynchronous-functors">an asynchronous functor</a>. </p> <p> There are several standard ways you can combine or transform combinations of functors. </p> <h3 id="70383da35af346f6b2dc3095a1bf7273"> A partial catalogue <a href="#70383da35af346f6b2dc3095a1bf7273" title="permalink">#</a> </h3> <p> The following relationships often come in handy - particularly those that top this list: </p> <ul> <li><a href="/2022/07/18/natural-transformations">Natural transformations</a></li> <li>Traversals</li> <li>Functor compositions</li> <li>Functor products</li> <li>Functor sums</li> </ul> <p> This list is hardly complete, and I may add to it in the future. Compared to some of the other subtopics of <a href="/2017/10/04/from-design-patterns-to-category-theory">the larger articles series on universal abstractions</a>, this catalogue is more heterogeneous. It collects various ways that functors can relate to each other, but uses disparate concepts and abstractions, rather than a single general idea (like a <a href="/2018/12/24/bifunctors">bifunctor</a>, <a href="/2017/10/06/monoids">monoid</a>, or <a href="/2019/04/29/catamorphisms">catamorphism</a>). </p> <p> Keep in mind when reading these articles that all <a href="/2022/03/28/monads">monads</a> are also functors and applicative functors, so what applies to functors also applies to monads. </p> <h3 id="1a4f0850f8974b59ab44eed352b0daf7"> Conclusion <a href="#1a4f0850f8974b59ab44eed352b0daf7" title="permalink">#</a> </h3> <p> You can use a single functor in isolation, or you can combine more than one. Most of the relationships described in this articles series work for all (lawful) functors, but traversals require applicative functors and functors that are 'foldable' (i.e. a catamorphism exists). </p> <p> <strong>Next:</strong> <a href="/2022/07/18/natural-transformations">Natural transformations</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>. Get and Put State https://blog.ploeh.dk/2022/07/04/get-and-put-state 2022-07-04T09:15:00+00:00 Mark Seemann <div id="post"> <p> <em>A pair of standard helper functions for the State monad. An article for object-oriented programmers.</em> </p> <p> The <a href="/2022/06/20/the-state-monad">State monad</a> is completely defined by <a href="/2022/03/28/monads">its two defining functions</a> (<code>SelectMany</code> and <code>Return</code>). While you can get by without them, two additional helper functions (<em>get</em> and <em>put</em>) are so convenient that they're typically included. To be clear, they're not part of the State <em>monad</em> - rather, you can consider them part of what we may term a <em>standard State API</em>. </p> <p> In short, <em>get</em> is a function that, as the name implies, gets the state while inside the State monad, and <em>put</em> replaces the state with a new value. </p> <p> Later in this article, I'll show how to implement these two functions, as well as a usage example. Before we get to that, however, I want to show a motivating example. In other words, an example that doesn't use <em>get</em> and <em>put</em>. </p> <p> The code shown in this article uses the C# State implementation from <a href="/2022/06/20/the-state-monad">the State monad article</a>. </p> <h3 id="62936af6492e474cb1f6afd919bc2cde"> Aggregator <a href="#62936af6492e474cb1f6afd919bc2cde" title="permalink">#</a> </h3> <p> Imagine that you have to implement a simple <a href="https://www.enterpriseintegrationpatterns.com/Aggregator.html">Aggregator</a>. </p> <blockquote> <p> "How do we combine the results of individual but related messages so that they can be processed as a whole?" </p> <p> [...] "Use a stateful filter, an <em>Aggregator</em>, to collect and store individual messages until it receives a complete set of related messages. Then, the <em>Aggregator</em> publishes a single message distilled from the individual messages." </p> <footer><cite><a href="/ref/eip">Enterprise Integration Patterns</a></cite></footer> </blockquote> <p> The example that I'll give here is simplified and mostly focuses on how to use the State monad to implement the desired behaviour. The book Enterprise Integration Patterns starts with a simple example where messages arrive with a <a href="https://www.enterpriseintegrationpatterns.com/CorrelationIdentifier.html">correlation ID</a> as an integer. The message payload is also a an integer, just to keep things simple. The Aggregator should only publish an aggregated message once it has received three correlated messages. </p> <p> Using the State monad, you could implement an Aggregator 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;">Aggregator</span>&nbsp;: &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;IReadOnlyDictionary&lt;<span style="color:blue;">int</span>,&nbsp;IReadOnlyCollection&lt;<span style="color:blue;">int</span>&gt;&gt;,&nbsp;Maybe&lt;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;&gt;&gt; { &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;correlationId; &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;value; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Aggregator</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">correlationId</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">value</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.correlationId&nbsp;=&nbsp;correlationId; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.value&nbsp;=&nbsp;value; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;Maybe&lt;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;&gt;,&nbsp;IReadOnlyDictionary&lt;<span style="color:blue;">int</span>,&nbsp;IReadOnlyCollection&lt;<span style="color:blue;">int</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Run</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IReadOnlyDictionary&lt;<span style="color:blue;">int</span>,&nbsp;IReadOnlyCollection&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(state.TryGetValue(correlationId,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">coll</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;(coll.Count&nbsp;==&nbsp;2) &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;">var</span>&nbsp;<span style="color:#1f377f;">retVal</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tuple.Create(coll.ElementAt(0),&nbsp;coll.ElementAt(1),&nbsp;value); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newState</span>&nbsp;=&nbsp;state.Remove(correlationId); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(retVal.ToMaybe(),&nbsp;newState); &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:#8f08c4;">else</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;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newColl</span>&nbsp;=&nbsp;coll.Append(value); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newState</span>&nbsp;=&nbsp;state.Replace(correlationId,&nbsp;newColl); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(<span style="color:blue;">new</span>&nbsp;Maybe&lt;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;&gt;(),&nbsp;newState); &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:#8f08c4;">else</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;">var</span>&nbsp;<span style="color:#1f377f;">newColl</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;value&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newState</span>&nbsp;=&nbsp;state.Add(correlationId,&nbsp;newColl); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(<span style="color:blue;">new</span>&nbsp;Maybe&lt;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;&gt;(),&nbsp;newState); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The <code>Aggregator</code> class implements the <code>IState&lt;S, T&gt;</code> interface. The full generic type is something of a mouthful, though. </p> <p> The state type (<code>S</code>) is <code>IReadOnlyDictionary&lt;<span style="color:blue;">int</span>,&nbsp;IReadOnlyCollection&lt;<span style="color:blue;">int</span>&gt;&gt;</code> - in other words, a dictionary of collections. Each entry in the dictionary is keyed by a correlation ID. Each value is a collection of messages that belong to that ID. Keep in mind that, in order to keep the example simple, each message is just a number (an <code>int</code>). </p> <p> The value to produce (<code>T</code>) is <code>Maybe&lt;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;&gt;</code>. This code example uses <a href="/2022/04/25/the-maybe-monad">this implementation of the Maybe monad</a>. The value produced may or may not be empty, depending on whether the Aggregator has received all three required messages in order to produce an aggregated message. Again, for simplicity, the aggregated message is just a triple (a three-tuple). </p> <p> The <code>Run</code> method starts by querying the <code>state</code> dictionary for an entry that corresponds to the <code>correlationId</code>. This entry may or may not be present. If the message is the first in a series of three, there will be no entry, but if it's the second or third message, the entry will be present. </p> <p> In that case, the <code>Run</code> method checks the <code>Count</code> of the collection. If the <code>Count</code> is <code>2</code>, it means that two other messages with the same <code>correlationId</code> was already received. This means that the <code>Aggregator</code> is now handling the third and final message. Thus, it creates the <code>retVal</code> tuple, removes the entry from the dictionary to create the <code>newState</code>, and returns both. </p> <p> If the <code>state</code> contains an entry for the <code>correlationId</code>, but the <code>Count</code> isn't <code>2</code>, the <code>Run</code> method updates the entry by appending the <code>value</code>, updating the state to <code>newState</code>, and returns that together with an empty Maybe value. </p> <p> Finally, if there is no entry for the <code>correlationId</code>, the <code>Run</code> method creates a new collection containing only the <code>value</code>, adds it to the <code>state</code> dictionary, and returns the <code>newState</code> together with an empty Maybe value. </p> <h3 id="f8ed5ee8f1eb4f1499e283f2383962e9"> Message handler <a href="#f8ed5ee8f1eb4f1499e283f2383962e9" title="permalink">#</a> </h3> <p> A message handler could be a background service that receives messages from a durable queue, a REST endpoint, or based on some other technology. </p> <p> After it receives a message, a message handler would create a new instance of the <code>Aggregator</code>: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">a</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Aggregator(msg.CorrelationId,&nbsp;msg.Value);</pre> </p> <p> Since <code>Aggregator</code> implements the <code>IState&lt;S, T&gt;</code> interface, the object <code>a</code> represents a stateful computation. A message handler might keep the current state in memory, or rehydrate it from some persistent storage system. Keep in mind that the state must be of the type <code>IReadOnlyDictionary&lt;<span style="color:blue;">int</span>,&nbsp;IReadOnlyCollection&lt;<span style="color:blue;">int</span>&gt;&gt;</code>. Wherever it comes from, assume that this state is a variable called <code>s</code> (for <em>state</em>). </p> <p> The message handler can now <code>Run</code> the stateful computation by supplying <code>s</code>: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;a.Run(s);</pre> </p> <p> The result is a tuple where the first item is a Maybe value, and the second item is the new state. </p> <p> The message handler can now publish the triple if the Maybe value is populated. In any case, it can update the 'current' state with the new state. That's a nice little <a href="/2020/03/02/impureim-sandwich">impureim sandwich</a>. </p> <p> Notice how this design is different from a typical object-oriented solution. In object-oriented programming, you'd typically have an object than contains the state and then receives the run-time value as input to a method that might then mutate the state. <em>Data with behaviour</em>, as it's sometimes characterised. </p> <p> The State-based computation turns such a design on its head. The computation closes over the run-time values, and the state is supplied as an argument to the <code>Run</code> method. This is an example of the shift of perspective often required to think functionally, rather than object-oriented. <em>That's</em> why it takes time learning Functional Programming (FP); it's not about syntax. It's a different way to think. </p> <p> An object like the above <code>a</code> seems almost frivolous, since it's going to have a short lifetime. Calling code will create it only to call its <code>Run</code> method and then let it go out of scope to be garbage-collected. </p> <p> Of course, in a language more attuned to FP like <a href="https://www.haskell.org">Haskell</a>, it's a different story: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;h&nbsp;=&nbsp;handle&nbsp;(corrId&nbsp;msg)&nbsp;(val&nbsp;msg)</pre> </p> <p> Instead of creating an object using a constructor, you only pass the message values to a function called <code>handle</code>. The return value <code>h</code> is a State value that an overall message handler can then later run with a state <code>s</code>: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;(m,&nbsp;ns)&nbsp;=&nbsp;runState&nbsp;h&nbsp;s</pre> </p> <p> The return value is a tuple where <code>m</code> is the Maybe value that may or may not contain the aggregated message; <code>ns</code> is the new state. </p> <h3 id="6904a24cf4a242c98b6732b5fcb8a3d1"> Is this better? <a href="#6904a24cf4a242c98b6732b5fcb8a3d1" title="permalink">#</a> </h3> <p> Is this approach to state mutation better than the default kind of state mutation possible with most languages (including C#)? Why make things so complicated? </p> <p> There's more than one answer. First, in a language like Haskell, state mutation is in general not possible. While you <em>can</em> do state mutation with <a href="/2020/06/08/the-io-container">the IO container</a> in Haskell, this sets you completely free. You don't want to be free, because with freedom comes innumerable ways to shoot yourself in the foot. <a href="https://www.dotnetrocks.com/?show=1542">Constraints liberate</a>. </p> <p> While the IO monad allows uncontrolled state mutation (together with all sorts of other impure actions), the State monad constrains itself and callers to only one type of apparent mutation. The type of the state being 'mutated' is visible in the type system, and that's the only type of value you can 'mutate' (in Haskell, that is). </p> <p> The State monad uses the type system to clearly communicate what the type of state is. Given a language like Haskell, or otherwise given sufficient programming discipline, you can tell from an object's type exactly what to expect. </p> <p> This also goes a long way to explain why monads are such an important concept in Functional Programming. When discussing FP, a common question is: <em>How do you perform side effects?</em> The answer, as may be already implied by this article, is that you use <a href="/2022/03/28/monads">monads</a>. The State monad for local state mutation, and the IO monad for 'global' side effects. </p> <h3 id="598094a7efc64e2685cf6196415bca01"> Get <a href="#598094a7efc64e2685cf6196415bca01" title="permalink">#</a> </h3> <p> Clearly you can write an implementation of <code>IState&lt;S, T&gt;</code> like the above <code>Aggregator</code> class. Must we always write a class that implements the interface in order to work within the State monad? </p> <p> Monads are all about composition. Usually, you can compose even complex behaviour from smaller building blocks. Just consider the <a href="/2022/04/19/the-list-monad">list monad</a>, which in C# is epitomised by the <code>IEnumerable&lt;T&gt;</code> interface. You can write quite complex logic using the building blocks of <a href="https://docs.microsoft.com/dotnet/api/system.linq.enumerable.where">Where</a>, <a href="https://docs.microsoft.com/dotnet/api/system.linq.enumerable.select">Select</a>, <a href="https://docs.microsoft.com/dotnet/api/system.linq.enumerable.aggregate">Aggregate</a>, <a href="https://docs.microsoft.com/dotnet/api/system.linq.enumerable.zip">Zip</a>, etcetera. </p> <p> Likewise, we should expect that to be the case with the State monad, and it is so. The useful extra combinators are <em>get</em> and <em>put</em>. </p> <p> The <em>get</em> function enables a composition to retrieve the current state. Given the <code>IState&lt;S, T&gt;</code> interface, you can implement it like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;S,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Get</span>&lt;<span style="color:#2b91af;">S</span>&gt;() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;GetState&lt;S&gt;(); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">GetState</span>&lt;<span style="color:#2b91af;">S</span>&gt;&nbsp;:&nbsp;IState&lt;S,&nbsp;S&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;S,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Run</span>(S&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(state,&nbsp;state); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The <code>Get</code> function represents a stateful computation that copies the <code>state</code> over to the 'value' dimension, so to speak. Notice that the return type is <code>IState&lt;S,&nbsp;S&gt;</code>. Copying the state over to the position of the <code>T</code> generic type means that it becomes accessible to the expressions that run inside of <code>Select</code> and <code>SelectMany</code>. </p> <p> You'll see an example once I rewrite the above <code>Aggregator</code> to be entirely based on composition, but in order to do that, I also need the <em>put</em> function. </p> <h3 id="224229b040ea417097a9de2ed1247953"> Put <a href="#224229b040ea417097a9de2ed1247953" title="permalink">#</a> </h3> <p> The <em>put</em> function enables you to write a new state value to the underlying state dimension. The implementation in the current code base looks like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;S,&nbsp;Unit&gt;&nbsp;<span style="color:#74531f;">Put</span>&lt;<span style="color:#2b91af;">S</span>&gt;(S&nbsp;<span style="color:#1f377f;">s</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;PutState&lt;S&gt;(s); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">PutState</span>&lt;<span style="color:#2b91af;">S</span>&gt;&nbsp;:&nbsp;IState&lt;S,&nbsp;Unit&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;S&nbsp;s; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">PutState</span>(S&nbsp;<span style="color:#1f377f;">s</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.s&nbsp;=&nbsp;s; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;Unit,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Run</span>(S&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(Unit.Default,&nbsp;s); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This implementation uses a <code>Unit</code> value to represent <code>void</code>. As usual, we have the problem in C-based languages that <code>void</code> isn't a value, but fortunately, <a href="/2018/01/15/unit-isomorphisms">unit is isomorphic to void</a>. </p> <p> Notice that the <code>Run</code> method ignores the current <code>state</code> and instead replaces it with the new state <code>s</code>. </p> <h3 id="c347a208b9524a1b85756a66cf53999c"> Look, no classes! <a href="#c347a208b9524a1b85756a66cf53999c" title="permalink">#</a> </h3> <p> The <code>Get</code> and <code>Put</code> functions are enough that we can now rewrite the functionality currently locked up in the <code>Aggregator</code> class. Instead of having to define a new <code>class</code> for that purpose, it's possible to compose our way to the same functionality by writing a function: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;IReadOnlyDictionary&lt;<span style="color:blue;">int</span>,&nbsp;IReadOnlyCollection&lt;<span style="color:blue;">int</span>&gt;&gt;,&nbsp;Maybe&lt;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;&gt;&gt; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#74531f;">Aggregate</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">correlationId</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">value</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;state&nbsp;<span style="color:blue;">in</span>&nbsp;State.Get&lt;IReadOnlyDictionary&lt;<span style="color:blue;">int</span>,&nbsp;IReadOnlyCollection&lt;<span style="color:blue;">int</span>&gt;&gt;&gt;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;mcoll&nbsp;=&nbsp;state.TryGetValue(correlationId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;retVal&nbsp;=&nbsp;<span style="color:blue;">from</span>&nbsp;coll&nbsp;<span style="color:blue;">in</span>&nbsp;mcoll.Where(<span style="color:#1f377f;">c</span>&nbsp;=&gt;&nbsp;c.Count&nbsp;==&nbsp;2) &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;Tuple.Create(coll.ElementAt(0),&nbsp;coll.ElementAt(1),&nbsp;value) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;newState&nbsp;=&nbsp;retVal &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Select(<span style="color:#1f377f;">_</span>&nbsp;=&gt;&nbsp;state.Remove(correlationId)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.GetValueOrFallback( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state.Replace( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;correlationId, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcoll &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Select(<span style="color:#1f377f;">coll</span>&nbsp;=&gt;&nbsp;coll.Append(value)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.GetValueOrFallback(<span style="color:blue;">new</span>[]&nbsp;{&nbsp;value&nbsp;}))) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;_&nbsp;<span style="color:blue;">in</span>&nbsp;State.Put(newState) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;retVal; }</pre> </p> <p> Okay, I admit that there's a hint of <a href="https://en.wikipedia.org/wiki/Code_golf">code golf</a> over this. It's certainly not <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatic</a> C#. To be clear, I'm not endorsing this style of C#; I'm only showing it to explain the abstraction offered by the State monad. <a href="/2019/03/18/the-programmer-as-decision-maker">Adopt such code at your own peril</a>. </p> <p> The first observation to be made about this code example is that it's written entirely in query syntax. There's a good reason for that. Query syntax is syntactic sugar on top of <code>SelectMany</code>, so you could, conceivably, also write the above expression using method call syntax. However, in order to make early values available to later expressions, you'd have to pass a lot of tuples around. For example, the above expression makes repeated use of <code>mcoll</code>, so had you been using method call syntax instead of query syntax, you would have had to pass that value on to subsequent computations as one item in a tuple. Not impossible, but awkward. With query syntax, all values remain in scope so that you can refer to them later. </p> <p> The expression starts by using <code>Get</code> to get the current state. The <code>state</code> variable is now available in the rest of the expression. </p> <p> The <code>state</code> is a dictionary, so the next step is to query it for an entry that corresponds to the <code>correlationId</code>. I've used an overload of <code>TryGetValue</code> that returns a Maybe value, which also explains (I hope) the <code>m</code> prefix of <code>mcoll</code>. </p> <p> Next, the expression filters <code>mcoll</code> and creates a triple if the <code>coll</code> has a <code>Count</code> of two. Notice that the nested query syntax expression (<code>from...select</code>) isn't running in the State monad, but rather in the <a href="/2022/04/25/the-maybe-monad">Maybe monad</a>. The result, <code>retVal</code>, is another Maybe value. </p> <p> That takes care of the 'return value', but we also need to calculate the new state. This happens in a somewhat roundabout way. The reason that it's not more straightforward is that C# query syntax doesn't allow branching (apart from the ternary <code>?..:</code> operator) and (this version of the language, at least) has weak pattern-matching abilities. </p> <p> Instead, it uses <code>retVal</code> and <code>mcoll</code> as indicators of how to update the state. If <code>retVal</code> is populated, it means that the <code>Aggregate</code> computation will return a triple, in which case it must <code>Remove</code> the entry from the state dictionary. On the other hand, if that's not the case, it must update the entry. Again, there are two options. If <code>mcoll</code> was already populated, it should be updated by appending the <code>value</code>. If not, a new entry containing only the <code>value</code> should be added. </p> <p> Finally, the expression uses <code>Put</code> to save the new state, after which it returns <code>retVal</code>. </p> <p> While this is far from idiomatic C# code, the point is that you can <em>compose</em> your way to the desired behaviour. You don't have to write a new class. Not that this is necessarily an improvement in C#. I'm mostly stating this to highlight a difference in philosophy. </p> <p> Of course, this is all much more elegant in Haskell, where the same functionality is as terse as this: </p> <p> <pre><span style="color:#2b91af;">handle</span>&nbsp;::&nbsp;(<span style="color:blue;">Ord</span>&nbsp;k,&nbsp;<span style="color:blue;">MonadState</span>&nbsp;(<span style="color:blue;">Map</span>&nbsp;k&nbsp;[a])&nbsp;m)&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;k&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;m&nbsp;(<span style="color:#2b91af;">Maybe</span>&nbsp;(a,&nbsp;a,&nbsp;a)) handle&nbsp;correlationId&nbsp;value&nbsp;=&nbsp;<span style="color:blue;">do</span> &nbsp;&nbsp;m&nbsp;&lt;-&nbsp;get &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;(retVal,&nbsp;newState)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">case</span>&nbsp;Map.<span style="color:blue;">lookup</span>&nbsp;correlationId&nbsp;m&nbsp;<span style="color:blue;">of</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Just&nbsp;[x,&nbsp;y]&nbsp;-&gt;&nbsp;(Just&nbsp;(x,&nbsp;y,&nbsp;value),&nbsp;Map.delete&nbsp;correlationId&nbsp;m) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Just&nbsp;&nbsp;_&nbsp;-&gt;&nbsp;(Nothing,&nbsp;Map.adjust&nbsp;(++&nbsp;[value])&nbsp;correlationId&nbsp;m) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nothing&nbsp;-&gt;&nbsp;(Nothing,&nbsp;Map.insert&nbsp;correlationId&nbsp;[value]&nbsp;m) &nbsp;&nbsp;put&nbsp;newState &nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;retVal</pre> </p> <p> Notice that this implementation also makes use of <code>get</code> and <code>put</code>. </p> <h3 id="2263fd914af84e0082c77a5ad2b9afe6"> Modify <a href="#2263fd914af84e0082c77a5ad2b9afe6" title="permalink">#</a> </h3> <p> The <code>Get</code> and <code>Put</code> functions are basic functions based on the State monad abstraction. These two functions, again, can be used to define some secondary helper functions, whereof <code>Modify</code> is one: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;S,&nbsp;Unit&gt;&nbsp;<span style="color:#74531f;">Modify</span>&lt;<span style="color:#2b91af;">S</span>&gt;(Func&lt;S,&nbsp;S&gt;&nbsp;<span style="color:#1f377f;">modify</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Get&lt;S&gt;().SelectMany(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;Put(modify(s))); }</pre> </p> <p> It wasn't required for the above <code>Aggregate</code> function, but here's a basic unit test that demonstrates how it works: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ModifyExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&nbsp;State.Modify((<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">i</span>)&nbsp;=&gt;&nbsp;i&nbsp;+&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;x.Run(1); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(2,&nbsp;actual.Item2); }</pre> </p> <p> It can be useful if you need to perform an 'atomic' state modification. For a realistic Haskell example, you may want to refer to my article <a href="/2019/03/11/an-example-of-state-based-testing-in-haskell">An example of state-based testing in Haskell</a>. </p> <h3 id="b1e1ba440a4f4b6aad12bc6721ba6f8b"> Gets <a href="#b1e1ba440a4f4b6aad12bc6721ba6f8b" title="permalink">#</a> </h3> <p> Another occasionally useful second-order helper function is <code>Gets</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#74531f;">Gets</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt;(Func&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Get&lt;S&gt;().Select(selector); }</pre> </p> <p> This function can be useful as a combinator if you need just a projection of the current state, instead of the whole state. </p> <p> Here's another basic unit test as an example: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">GetsExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&nbsp;State.Gets((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;x.Run(<span style="color:#a31515;">&quot;bar&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(Tuple.Create(3,&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>),&nbsp;actual); }</pre> </p> <p> While the above Aggregator example didn't require <code>Modify</code> or <code>Gets</code>, I wanted to include them here for completeness sake. </p> <h3 id="05a2046a71e94b85a3f5445df9669800"> F# <a href="#05a2046a71e94b85a3f5445df9669800" title="permalink">#</a> </h3> <p> Most of the code shown in this article has been C#, with the occasional Haskell code. You can also implement the State monad, as well as the helper methods, in <a href="https://fsharp.org">F#</a>, where it'd feel more natural to dispense with interfaces and instead work directly with functions. To make things a little clearer, you may want to define a type alias: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;State&lt;&#39;a,&nbsp;&#39;s&gt;&nbsp;=&nbsp;(&#39;s&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;&#39;a&nbsp;*&nbsp;&#39;s)</pre> </p> <p> You can now define a <code>State</code> module that works directly with that kind of function: </p> <p> <pre><span style="color:blue;">module</span>&nbsp;State&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;run&nbsp;state&nbsp;(f&nbsp;:&nbsp;State&lt;_,&nbsp;_&gt;)&nbsp;=&nbsp;f&nbsp;state &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;lift&nbsp;x&nbsp;state&nbsp;=&nbsp;x,&nbsp;state &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;map&nbsp;f&nbsp;x&nbsp;state&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;x&#39;,&nbsp;newState&nbsp;=&nbsp;run&nbsp;state&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;x&#39;,&nbsp;newState &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;bind&nbsp;(f&nbsp;:&nbsp;&#39;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;State&lt;&#39;b,&nbsp;&#39;s&gt;)&nbsp;(x&nbsp;:&nbsp;State&lt;&#39;a,&nbsp;&#39;s&gt;)&nbsp;state&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;x&#39;,&nbsp;newState&nbsp;=&nbsp;run&nbsp;state&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;run&nbsp;newState&nbsp;(f&nbsp;x&#39;) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;get&nbsp;state&nbsp;=&nbsp;state,&nbsp;state &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;put&nbsp;newState&nbsp;_&nbsp;=&nbsp;(),&nbsp;newState &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;modify&nbsp;f&nbsp;=&nbsp;get&nbsp;|&gt;&nbsp;map&nbsp;f&nbsp;|&gt;&nbsp;bind&nbsp;put</pre> </p> <p> This is code I originally wrote for <a href="https://codereview.stackexchange.com/a/139652/3878">a Code Review answer</a>. You can go there to see all the details, as well as a motivating example. </p> <p> I see that I never got around to add a <code>gets</code> function... I'll leave that as an exercise. </p> <p> In C#, I've based the example on an interface (<code>IState&lt;S, T&gt;</code>), but it would also be possible to implement the State monad as extension methods on <code>Func&lt;S, Tuple&lt;T, S&gt;&gt;</code>. Try it! It might be another good exercise. </p> <h3 id="994529b38af241b9ba6090f5d670bcc8"> Conclusion <a href="#994529b38af241b9ba6090f5d670bcc8" title="permalink">#</a> </h3> <p> The State monad usually comes with a few helper functions: <em>get</em>, <em>put</em>, <em>modify</em>, and <em>gets</em>. They can be useful as combinators you can use to compose a stateful combination from smaller building blocks, just like you can use LINQ to compose complex queries over data. </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>. Test Double clocks https://blog.ploeh.dk/2022/06/27/test-double-clocks 2022-06-27T05:44:00+00:00 Mark Seemann <div id="post"> <p> <em>A short exploration of replacing the system clock with Test Doubles.</em> </p> <p> In a comment to my article <a href="/2022/05/23/waiting-to-never-happen">Waiting to never happen</a>, <a href="https://github.com/ladeak">Laszlo</a> asks: </p> <blockquote> <p> "Why have you decided to make the date of the reservation relative to the SystemClock, and not the other way around? Would it be more deterministic to use a faked system clock instead?" </p> <footer><cite><a href="/2022/05/23/waiting-to-never-happen#c0b2e0bd555b5d5c5555c60bf11bff69">Laszlo</a></cite></footer> </blockquote> <p> The short answer is that I hadn't thought of the alternative. Not in this context, at least. </p> <p> It's a question worth exploring, which I will now proceed to do. </p> <h3 id="d7283861d9494c478b2bd8bb90218208"> Why IClock? <a href="#d7283861d9494c478b2bd8bb90218208" title="permalink">#</a> </h3> <p> The article in question discusses a unit test, which ultimately arrives at this: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">ChangeDateToSoldOutDate</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r1</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Some.Reservation.WithDate(DateTime.Now.AddDays(8).At(20,&nbsp;15)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r2</span>&nbsp;=&nbsp;r1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithId(Guid.NewGuid()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDayAfter() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithQuantity(10); &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;db.Grandfather.Add(r1); &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather.Add(r2); &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;r1.WithDate(r2.At).ToDto(); &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;sut.Put(r1.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>),&nbsp;dto); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">oRes</span>&nbsp;=&nbsp;Assert.IsAssignableFrom&lt;ObjectResult&gt;(actual); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StatusCodes.Status500InternalServerError, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oRes.StatusCode); }</pre> </p> <p> The keen reader may notice that the test passes a <code><span style="color:blue;">new</span>&nbsp;SystemClock()</code> to the <code>sut</code>. In case you're wondering what that is, here's the definition: </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;">SystemClock</span>&nbsp;:&nbsp;IClock { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;DateTime&nbsp;<span style="color:#74531f;">GetCurrentDateTime</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;DateTime.Now; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> While it should be possible to extrapolate the <code>IClock</code> interface from this code snippet, here it is for the sake of completeness: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IClock</span> { &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#74531f;">GetCurrentDateTime</span>(); }</pre> </p> <p> Since such an interface exists, why not use it in unit tests? </p> <p> That's possible, but I think it's worth highlighting what motivated this interface in the first place. If you're used to a certain style of test-driven development (TDD), you may think that interfaces exist in order to support TDD. They may. That's how I did TDD 15 years ago, but <a href="/2019/02/18/from-interaction-based-to-state-based-testing">not how I do it today</a>. </p> <p> The motivation for the <code>IClock</code> interface is another. It's there because the system clock is a source of impurity, just like random number generators, database queries, and web service invocations. In order to support <a href="/2020/03/23/repeatable-execution">repeatable execution</a>, it's useful to log the inputs and outputs of impure actions. This includes the system clock. </p> <p> The <code>IClock</code> interface doesn't exist in order to support unit testing, but in order to enable logging via the <a href="https://en.wikipedia.org/wiki/Decorator_pattern">Decorator</a> pattern: </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;">LoggingClock</span>&nbsp;:&nbsp;IClock { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">LoggingClock</span>(ILogger&lt;LoggingClock&gt;&nbsp;<span style="color:#1f377f;">logger</span>,&nbsp;IClock&nbsp;<span style="color:#1f377f;">inner</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger&nbsp;=&nbsp;logger; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Inner&nbsp;=&nbsp;inner; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;ILogger&lt;LoggingClock&gt;&nbsp;Logger&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IClock&nbsp;Inner&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;DateTime&nbsp;<span style="color:#74531f;">GetCurrentDateTime</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">output</span>&nbsp;=&nbsp;Inner.GetCurrentDateTime(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.LogInformation( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;{method}()&nbsp;=&gt;&nbsp;{output}&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(GetCurrentDateTime), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;output; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> All code in this article originates from the code base that accompanies <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. </p> <p> The web application is configured to decorate the <code>SystemClock</code> with the <code>LoggingClock</code>: </p> <p> <pre>services.AddSingleton&lt;IClock&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;sp.GetService&lt;ILogger&lt;LoggingClock&gt;&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;LoggingClock(logger,&nbsp;<span style="color:blue;">new</span>&nbsp;SystemClock()); });</pre> </p> <p> While the motivation for the <code>IClock</code> interface wasn't to support testing, now that it exists, would it be useful for unit testing as well? </p> <h3 id="3bf52db0c892409dbc372a83293a8992"> A Stub clock <a href="#3bf52db0c892409dbc372a83293a8992" title="permalink">#</a> </h3> <p> As a first effort, we might try to add a <a href="http://xunitpatterns.com/Test%20Stub.html">Stub</a> clock: </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;">ConstantClock</span>&nbsp;:&nbsp;IClock { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;DateTime&nbsp;dateTime; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ConstantClock</span>(DateTime&nbsp;<span style="color:#1f377f;">dateTime</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.dateTime&nbsp;=&nbsp;dateTime; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;This&nbsp;default&nbsp;value&nbsp;is&nbsp;more&nbsp;or&nbsp;less&nbsp;arbitrary.&nbsp;I&nbsp;chose&nbsp;it&nbsp;as&nbsp;the&nbsp;date</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;and&nbsp;time&nbsp;I&nbsp;wrote&nbsp;these&nbsp;lines&nbsp;of&nbsp;code,&nbsp;which&nbsp;also&nbsp;has&nbsp;the&nbsp;implication</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;that&nbsp;it&nbsp;was&nbsp;immediately&nbsp;a&nbsp;time&nbsp;in&nbsp;the&nbsp;past.&nbsp;The&nbsp;actual&nbsp;value&nbsp;is,</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;however,&nbsp;irrelevant.</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;IClock&nbsp;Default&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;ConstantClock(<span style="color:blue;">new</span>&nbsp;DateTime(2022,&nbsp;6,&nbsp;19,&nbsp;9,&nbsp;25,&nbsp;0)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;DateTime&nbsp;<span style="color:#74531f;">GetCurrentDateTime</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;dateTime; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This implementation always returns the same date and time. I called it <code>ConstantClock</code> for that reason. </p> <p> It's trivial to replace the <code>SystemClock</code> with a <code>ConstantClock</code> in the above test: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">ChangeDateToSoldOutDate</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">clock</span>&nbsp;=&nbsp;ConstantClock.Default; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r1</span>&nbsp;=&nbsp;Some.Reservation.WithDate( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clock.GetCurrentDateTime().AddDays(8).At(20,&nbsp;15)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r2</span>&nbsp;=&nbsp;r1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithId(Guid.NewGuid()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDayAfter() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithQuantity(10); &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;db.Grandfather.Add(r1); &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather.Add(r2); &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;clock, &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;r1.WithDate(r2.At).ToDto(); &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;sut.Put(r1.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>),&nbsp;dto); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">oRes</span>&nbsp;=&nbsp;Assert.IsAssignableFrom&lt;ObjectResult&gt;(actual); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StatusCodes.Status500InternalServerError, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oRes.StatusCode); }</pre> </p> <p> As you can see, however, it doesn't seem to be enabling any simplification of the test. It still needs to establish that <code>r1</code> and <code>r2</code> relates to each other as required by the test case, as well as establish that they are valid reservations in the future. </p> <p> You may protest that this is straw man argument, and that it would make the test both simpler and more readable if it would, instead, use explicit, hard-coded values. That's a fair criticism, so I'll get back to that later. </p> <h3 id="58fe168e8266401990d62641020db9ac"> Fragility <a href="#58fe168e8266401990d62641020db9ac" title="permalink">#</a> </h3> <p> Before examining the above criticism, there's something more fundamental that I want to get out of the way. I find a Stub clock icky. </p> <p> It works in this case, but may lead to fragile tests. What happens, for example, if another programmer comes by and adds code like this to the System Under Test (SUT)? </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">now</span>&nbsp;=&nbsp;Clock.GetCurrentDateTime(); <span style="color:green;">//&nbsp;Sabotage:</span> <span style="color:#8f08c4;">while</span>&nbsp;(Clock.GetCurrentDateTime()&nbsp;-&nbsp;now&nbsp;&lt;&nbsp;TimeSpan.FromMilliseconds(1)) {&nbsp;}</pre> </p> <p> As the comment suggests, in this case it's pure sabotage. I don't think that anyone would deliberately do something like this. This code snippet even sits in an asynchronous method, and in .NET 'everyone' knows that if you want to suspend execution in an asynchronous method, you should use <a href="https://docs.microsoft.com/dotnet/api/system.threading.tasks.task.delay">Task.Delay</a>. I rather intend this code snippet to indicate that keeping time constant, as <code>ConstantClock</code> does, can be fatal. </p> <p> If someone comes by and attempts to implement any kind of time-sensitive logic based on an injected <code>IClock</code>, the consequences could be dire. With the above sabotage, for example, the test hangs forever. </p> <p> When I originally <a href="/2021/01/11/waiting-to-happen">refactored time-sensitive tests</a>, it was because I didn't appreciate having such ticking bombs lying around. A <code>ConstantClock</code> isn't <em>ticking</em> (that's the problem), but it still seems like a booby trap. </p> <h3 id="d58309147ef6450589ed0b5c69b33b30"> Offset clock <a href="#d58309147ef6450589ed0b5c69b33b30" title="permalink">#</a> </h3> <p> It seems intuitive that a clock that doesn't go isn't very useful. Perhaps we can address that problem by setting the clock back. Not just a few hours, but days or years: </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;">OffsetClock</span>&nbsp;:&nbsp;IClock { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;TimeSpan&nbsp;offset; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">OffsetClock</span>(DateTime&nbsp;<span style="color:#1f377f;">origin</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;=&nbsp;DateTime.Now&nbsp;-&nbsp;origin; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IClock&nbsp;<span style="color:#74531f;">Start</span>(DateTime&nbsp;<span style="color:#1f377f;">at</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;OffsetClock(at); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;This&nbsp;default&nbsp;value&nbsp;is&nbsp;more&nbsp;or&nbsp;less&nbsp;arbitrary.&nbsp;I&nbsp;just&nbsp;picked&nbsp;the&nbsp;same</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;date&nbsp;and&nbsp;time&nbsp;as&nbsp;ConstantClock&nbsp;(which&nbsp;see).</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;IClock&nbsp;Default&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Start(at:&nbsp;<span style="color:blue;">new</span>&nbsp;DateTime(2022,&nbsp;6,&nbsp;19,&nbsp;9,&nbsp;25,&nbsp;0)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;DateTime&nbsp;<span style="color:#74531f;">GetCurrentDateTime</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;DateTime.Now&nbsp;-&nbsp;offset; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> An <code>OffsetClock</code> object starts ticking as soon as it's created, but it ticks at the same pace as the system clock. Time still passes. Rather than a Stub, I think that this implementation qualifies as a <a href="http://xunitpatterns.com/Fake%20Object.html">Fake</a>. </p> <p> Using it in a test is as easy as using the <code>ConstantClock</code>: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">ChangeDateToSoldOutDate</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">clock</span>&nbsp;=&nbsp;OffsetClock.Default; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r1</span>&nbsp;=&nbsp;Some.Reservation.WithDate( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clock.GetCurrentDateTime().AddDays(8).At(20,&nbsp;15)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r2</span>&nbsp;=&nbsp;r1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithId(Guid.NewGuid()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDayAfter() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithQuantity(10); &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;db.Grandfather.Add(r1); &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather.Add(r2); &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;clock, &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;r1.WithDate(r2.At).ToDto(); &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;sut.Put(r1.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>),&nbsp;dto); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">oRes</span>&nbsp;=&nbsp;Assert.IsAssignableFrom&lt;ObjectResult&gt;(actual); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StatusCodes.Status500InternalServerError, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oRes.StatusCode); }</pre> </p> <p> The only change from the version that uses <code>ConstantClock</code> is the definition of the <code>clock</code> variable. </p> <p> This test can withstand the above sabotage, because time still passes at normal pace. </p> <h3 id="06f0ace3806e41139e30106aeb77e0e1"> Explicit dates <a href="#06f0ace3806e41139e30106aeb77e0e1" title="permalink">#</a> </h3> <p> Above, I promised to return to the criticism that the test is overly abstract. Now that it's possible to directly control time, perhaps it'd simplify the test if we could use hard-coded dates and times, instead of all that relative-time machinery: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">ChangeDateToSoldOutDate</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r1</span>&nbsp;=&nbsp;Some.Reservation.WithDate( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DateTime(2022,&nbsp;6,&nbsp;27,&nbsp;20,&nbsp;15,&nbsp;0)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r2</span>&nbsp;=&nbsp;r1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithId(Guid.NewGuid()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithDate(<span style="color:blue;">new</span>&nbsp;DateTime(2022,&nbsp;6,&nbsp;28,&nbsp;20,&nbsp;15,&nbsp;0)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithQuantity(10); &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;db.Grandfather.Add(r1); &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather.Add(r2); &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;OffsetClock.Start(at:&nbsp;<span style="color:blue;">new</span>&nbsp;DateTime(2022,&nbsp;6,&nbsp;19,&nbsp;13,&nbsp;43,&nbsp;0)), &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;r1.WithDate(r2.At).ToDto(); &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;sut.Put(r1.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>),&nbsp;dto); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">oRes</span>&nbsp;=&nbsp;Assert.IsAssignableFrom&lt;ObjectResult&gt;(actual); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StatusCodes.Status500InternalServerError, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oRes.StatusCode); }</pre> </p> <p> Yeah, not really. This isn't worse, but neither is it better. It's the same size of code, and while the dates are now explicit (<a href="https://peps.python.org/pep-0020/">which, ostensibly, is better</a>), the reader now has to deduce the relationship between the clock offset, <code>r1</code>, and <code>r2</code>. I'm not convinced that this is an improvement. </p> <h3 id="62ae3d8257b64496ae7e82930438daa5"> Determinism <a href="#62ae3d8257b64496ae7e82930438daa5" title="permalink">#</a> </h3> <p> In the original comment, Laszlo asked if it would be more deterministic to use a Fake system clock instead. This seems to imply that using the system clock is nondeterministic. Granted, it is when not used with care. </p> <p> On the other hand, when used as shown in the initial test, it's <em>almost</em> deterministic. What time-related circumstances would have to come around for the test to fail? </p> <p> The important precondition is that both reservations are in the future. The test picks a date eight days in the future. How might that precondition fail? </p> <p> The only failure condition I can think of is if test execution somehow gets suspended <em>after</em> <code>r1</code> and <code>r2</code> are initialised, but <em>before</em> calling <code>sut.Put</code>. If you run the test on a laptop and put it to sleep for more than eight days, you may be so extremely lucky (or unlucky, depending on how you look at it) that this turns out to be the case. When execution resumes, the reservations are now in the past, and <code>sut.Put</code> will fail because of that. </p> <p> I'm not convinced that this is at all likely, and it's not a scenario that I'm inclined to take into account. </p> <p> And in any case, the test variation that uses <code>OffsetClock</code> is as 'vulnerable' to that scenario as the <code>SystemClock</code>. The only <a href="https://martinfowler.com/bliki/TestDouble.html">Test Double</a> not susceptible to such a scenario is <code>ConstantClock</code>, but as you have seen, this has more immediate problems. </p> <h3 id="0d09375b62d94fc287cb70568e0b7f1a"> Conclusion <a href="#0d09375b62d94fc287cb70568e0b7f1a" title="permalink">#</a> </h3> <p> If you've read or seen a sufficient amount of time-travel science fiction, you know that it's not a good idea to try to change time. This also seems to be the case here. At least, I can see a few disadvantages to using Test Double clocks, but no clear advantages. </p> <p> The above is, of course, only one example, but the concern of how to control the passing of time in unit testing isn't new to me. This is something that have been an issue on and off since I started with TDD in 2003. I keep coming back to the notion that the simplest solution is to use as many <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a> as possible, combined with a few impure actions that may require explicit use of dates and times relative to the system clock, as shown in previous articles. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="1d4fb68f3b5542e9897c82ad5c342a8a"> <div class="comment-author"><a href="https://github.com/ladeak">Laszlo</a></div> <div class="comment-content"> <p> I agree to most described in this post. However, I still find StubClock as my 'default' approach. I summarized the my reasons in this <a href="https://gist.github.com/ladeak/4f6ece31e941e28bafa1fca844d9fe3b">gist reply</a>. </p> </div> <div class="comment-date">2022-06-30 7:43 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 State monad https://blog.ploeh.dk/2022/06/20/the-state-monad 2022-06-20T21:52:00+00:00 Mark Seemann <div id="post"> <p> <em>Stateful computations as a monad. An example 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>. A previous article described <a href="/2021/07/19/the-state-functor">the State functor</a>. As is the case with many (but not all) <a href="/2018/03/22/functors">functors</a>, this one also forms a monad. </p> <p> This article continues where the State functor article stopped. It uses the same code base. </p> <h3 id="0309f41b7a434781a1640f18ac7cea30"> SelectMany <a href="#0309f41b7a434781a1640f18ac7cea30" 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>. Given the <code>IState&lt;S, T&gt;</code> interface defined in the State functor article, you can implement <code>SelectMany</code> like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;S,&nbsp;T1&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<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;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;IState&lt;S,&nbsp;T1&gt;&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;SelectManyState&lt;S,&nbsp;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;">SelectManyState</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;&nbsp;:&nbsp;IState&lt;S,&nbsp;T1&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;T,&nbsp;IState&lt;S,&nbsp;T1&gt;&gt;&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">SelectManyState</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;IState&lt;S,&nbsp;T1&gt;&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;Tuple&lt;T1,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Run</span>(S&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tuple&lt;T,&nbsp;S&gt;&nbsp;<span style="color:#1f377f;">tuple</span>&nbsp;=&nbsp;source.Run(state); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IState&lt;S,&nbsp;T1&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;selector(tuple.Item1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;projection.Run(tuple.Item2); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> As <code>SelectMany</code> implementations go, this is easily the most complex so far in this article series. While it looks complex, it really isn't. It's only complicated. </p> <p> The three lines of code in the <code>Run</code> method does most of the work. The rest is essentially <a href="/2019/12/16/zone-of-ceremony">ceremony</a> required because C# doesn't have language features like object expressions. </p> <p> To be fair, part of the boilerplate is also caused by using an interface instead of functions. In <a href="https://fsharp.org">F#</a> you could get by with as little as this: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;bind&nbsp;(f&nbsp;:&nbsp;&#39;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;State&lt;&#39;b,&nbsp;&#39;s&gt;)&nbsp;(x&nbsp;:&nbsp;State&lt;&#39;a,&nbsp;&#39;s&gt;)&nbsp;state&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;x&#39;,&nbsp;newState&nbsp;=&nbsp;run&nbsp;state&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;run&nbsp;newState&nbsp;(f&nbsp;x&#39;)</pre> </p> <p> I found an F# State implementation on my hard drive that turned out to originate from <a href="https://codereview.stackexchange.com/a/139652/3878">this Code Review answer</a>. You can go there to see it in context. </p> <p> The <code>SelectMany</code> method first runs the <code>source</code> with the supplied <code>state</code>. This produces a tuple with a value and a new state. The value is <code>tuple.Item1</code>, which has the type <code>T</code>. The method proceeds to use that value to call the <code>selector</code>, which produces a new State value. Finally, the method runs the <code>projection</code> with the new state (<code>tuple.Item2</code>). </p> <p> Monadic bind becomes useful when you have more than one function that returns a monadic value. Consider a code snippet like this: </p> <p> <pre>IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Switch(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>).SelectMany(<span style="color:#1f377f;">txt</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;VowelExpander(txt));</pre> </p> <p> This uses the silly <code>VowelExpander</code> class from <a href="/2021/07/19/the-state-functor">the State functor article</a>, as well as this new frivolous State 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;">Switch</span>&nbsp;:&nbsp;IState&lt;<span style="color:blue;">int</span>,&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;option1; &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;option2; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Switch</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">option1</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">option2</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.option1&nbsp;=&nbsp;option1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.option2&nbsp;=&nbsp;option2; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#74531f;">Run</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(0&nbsp;&lt;=&nbsp;state) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(option1,&nbsp;state); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newState</span>&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(option2,&nbsp;newState); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Both <code>Switch</code> and <code>VowelExpander</code> are State objects. If <code>SelectMany</code> didn't flatten as it goes, composition would have resulted in a nested State value. You'll see an example later in this article. </p> <h3 id="edc7d11f7fbd4b72b6b16858617fbbab"> Query syntax <a href="#edc7d11f7fbd4b72b6b16858617fbbab" title="permalink">#</a> </h3> <p> Monads also enable query syntax in C# (just like they enable other kinds of syntactic sugar in languages like F# 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;IState&lt;S,&nbsp;T1&gt;&nbsp;<span style="color:#74531f;">SelectMany</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">U</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;IState&lt;S,&nbsp;U&gt;&gt;&nbsp;<span style="color:#1f377f;">k</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;U,&nbsp;T1&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 already predicted in the <a href="/2022/03/28/monads">monad introduction</a>, this boilerplate overload is always implemented in the same way. Only the signature changes. With it, you could instead write the above composition of <code>Switch</code> and <code>VowelExpander</code> like this: </p> <p> <pre>IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&nbsp;<span style="color:blue;">from</span>&nbsp;txt&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Switch(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;bar&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;<span style="color:blue;">from</span>&nbsp;txt1&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:blue;">new</span>&nbsp;VowelExpander(txt) &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;txt1;</pre> </p> <p> That example requires a new variable (<code>txt1</code>). Given that it's often difficult to come up with good variable names, this doesn't look like much of an improvement. Still, it's possible. </p> <h3 id="048b4a03e28a4f7baca996319ca54627"> Join <a href="#048b4a03e28a4f7baca996319ca54627" 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>IState&lt;S, 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;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#74531f;">Join</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;IState&lt;S,&nbsp;IState&lt;S,&nbsp;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> Here's a way you can use it: </p> <p> <pre>IState&lt;<span style="color:blue;">int</span>,&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<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;Switch(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>).Select(<span style="color:#1f377f;">txt</span>&nbsp;=&gt;&nbsp;(IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;)<span style="color:blue;">new</span>&nbsp;VowelExpander(txt)); IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">flattened</span>&nbsp;=&nbsp;nested.Join();</pre> </p> <p> Of the three examples involving <code>Switch</code> and <code>VowelExpander</code>, this one most clearly emphasises the idea that a monad is a functor you can flatten. Using <code>Select</code> (instead of <code>SelectMany</code>) creates a nested State value when you try to compose the two together. With <code>Join</code> you can flatten them. </p> <p> Not that doing it this way is better in any way. In practice, you'll mostly use either <code>SelectMany</code> or query syntax. It's a rare case when I use something like <code>Join</code>. </p> <h3 id="57fff60c94da4624965da2eb87e46f17"> Return <a href="#57fff60c94da4624965da2eb87e46f17" 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): </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#74531f;">Return</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ReturnState&lt;S,&nbsp;T&gt;(x); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ReturnState</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt;&nbsp;:&nbsp;IState&lt;S,&nbsp;T&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;T&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ReturnState</span>(T&nbsp;<span style="color:#1f377f;">x</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.x&nbsp;=&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;T,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Run</span>(S&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(x,&nbsp;state); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Like the above <code>SelectMany</code> implementation, this is easily the most complicated <code>Return</code> implementation so far shown in this article series. Again, however, most of it is just boilerplate necessitated by C#'s lack of certain language features (most notably object expressions). And again, this is also somewhat unfair because I could have chosen to demonstrate the State monad using <code>Func&lt;S, Tuple&lt;T, S&gt;&gt;</code> instead of an interface. (This would actually be a good exercise; try it!) </p> <p> If you strip away all the boilerplate, the implementation is a trivial one-liner (the <code>Run</code> method), as also witnessed by this equivalent F# function that just returns a tuple: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;lift&nbsp;x&nbsp;state&nbsp;=&nbsp;x,&nbsp;state</pre> </p> <p> When partially applied (<code>State.lift&nbsp;x</code>) that function returns a State value (i.e. a <code>&#39;s&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;&#39;a&nbsp;*&nbsp;&#39;s</code> function). </p> <p> Again, you can see that F# code in context in <a href="https://codereview.stackexchange.com/a/139652/3878">this Code Review answer</a>. </p> <h3 id="7cff668e401e40a4b7ee005683e341f6"> Left identity <a href="#7cff668e401e40a4b7ee005683e341f6" 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>. Now that this is done, let's see what the laws look like for the State monad, starting with the left identity law. </p> <p> <pre>[Theory] [InlineData(DayOfWeek.Monday,&nbsp;2)] [InlineData(DayOfWeek.Tuesday,&nbsp;0)] [InlineData(DayOfWeek.Wednesday,&nbsp;19)] [InlineData(DayOfWeek.Thursday,&nbsp;42)] [InlineData(DayOfWeek.Friday,&nbsp;2112)] [InlineData(DayOfWeek.Saturday,&nbsp;90)] [InlineData(DayOfWeek.Sunday,&nbsp;210)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">LeftIdentity</span>(DayOfWeek&nbsp;<span style="color:#1f377f;">a</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">state</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;DayOfWeek,&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;DayOfWeek&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;State.Return&lt;<span style="color:blue;">int</span>,&nbsp;DayOfWeek&gt;; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;DayOfWeek,&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">dow</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;VowelExpander(dow.ToString()); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(@return(a).SelectMany(h).Run(state),&nbsp;h(a).Run(state)); }</pre> </p> <p> In order to compare the two State values, the test has to <code>Run</code> them and then compare the return values. </p> <h3 id="e47c76d943214e0399bf1ab4ad1e843c"> Right identity <a href="#e47c76d943214e0399bf1ab4ad1e843c" title="permalink">#</a> </h3> <p> In a similar manner, we can showcase the right identity law as a test. </p> <p> <pre>[Theory] [InlineData(&nbsp;<span style="color:blue;">true</span>,&nbsp;0)] [InlineData(&nbsp;<span style="color:blue;">true</span>,&nbsp;1)] [InlineData(&nbsp;<span style="color:blue;">true</span>,&nbsp;8)] [InlineData(<span style="color:blue;">false</span>,&nbsp;0)] [InlineData(<span style="color:blue;">false</span>,&nbsp;2)] [InlineData(<span style="color:blue;">false</span>,&nbsp;7)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">RightIdentity</span>(<span style="color:blue;">bool</span>&nbsp;<span style="color:#1f377f;">a</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">state</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">bool</span>,&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">b</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;VowelExpander(b.ToString()); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;State.Return&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;; &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<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).Run(state),&nbsp;m.Run(state)); }</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="4a3a29ab66304776b7bc6676d1675762"> Associativity <a href="#4a3a29ab66304776b7bc6676d1675762" 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. For the purpose of demonstrating the law, any three pure functions will do. While the following functions are silly and not at all 'realistic', they have the virtue of being as simple as they can be (while still providing a bit of variety). They don't 'mean' anything, so don't worry too much about their behaviour. It is, as far as I can tell, nonsensical. Later articles will show some more realistic examples of the State monad in action. </p> <p> <pre><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;">F</span>&nbsp;:&nbsp;IState&lt;DateTime,&nbsp;<span style="color:blue;">int</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;s; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">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:blue;">this</span>.s&nbsp;=&nbsp;s; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#74531f;">Run</span>(DateTime&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&nbsp;s.Length; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newState</span>&nbsp;=&nbsp;state.AddDays(i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newValue</span>&nbsp;=&nbsp;i&nbsp;+&nbsp;state.Month; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(newValue,&nbsp;newState); &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;">G</span>&nbsp;:&nbsp;IState&lt;DateTime,&nbsp;TimeSpan&gt; { &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;i; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">G</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">i</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.i&nbsp;=&nbsp;i; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;TimeSpan,&nbsp;DateTime&gt;&nbsp;<span style="color:#74531f;">Run</span>(DateTime&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newState</span>&nbsp;=&nbsp;state.AddYears(i&nbsp;-&nbsp;state.Year); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newValue</span>&nbsp;=&nbsp;TimeSpan.FromMinutes(i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(newValue,&nbsp;newState); &nbsp;&nbsp;&nbsp;&nbsp;} } <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;">H</span>&nbsp;:&nbsp;IState&lt;DateTime,&nbsp;<span style="color:blue;">bool</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;TimeSpan&nbsp;duration; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">H</span>(TimeSpan&nbsp;<span style="color:#1f377f;">duration</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.duration&nbsp;=&nbsp;duration; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;<span style="color:blue;">bool</span>,&nbsp;DateTime&gt;&nbsp;<span style="color:#74531f;">Run</span>(DateTime&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newState</span>&nbsp;=&nbsp;state&nbsp;-&nbsp;duration; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#1f377f;">newValue</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newState.DayOfWeek&nbsp;==&nbsp;DayOfWeek.Saturday&nbsp;||&nbsp;newState.DayOfWeek&nbsp;==&nbsp;DayOfWeek.Sunday; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(newValue,&nbsp;newState); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Armed with these three classes, we can now demonstrate the Associativity law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;2022-03-23&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;2021-12-23T18:05&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;baz&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;1984-01-06T00:33&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;DateTime&nbsp;<span style="color:#1f377f;">state</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;IState&lt;DateTime,&nbsp;<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;<span style="color:blue;">new</span>&nbsp;F(s); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;IState&lt;DateTime,&nbsp;TimeSpan&gt;&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;G(i); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TimeSpan,&nbsp;IState&lt;DateTime,&nbsp;<span style="color:blue;">bool</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;H(ts); &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;DateTime,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;f(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.SelectMany(g).SelectMany(h).Run(state), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h)).Run(state)); }</pre> </p> <p> The version of <a href="https://xunit.net">xUnit.net</a> I'm using for these examples (xUnit.net 2.2.0 on .NET Framework 4.6.1 - I may already have hinted that this is an old code base I had lying around) comes with a converter between <code>string</code> and <code>DateTime</code>, which explains why the <code>[InlineData]</code> can supply <code>DateTime</code> values as <code>string</code>s. </p> <h3 id="bf812a647a5c412da53f52f63989ca1d"> Conclusion <a href="#bf812a647a5c412da53f52f63989ca1d" title="permalink">#</a> </h3> <p> For people coming from an imperative or object-oriented background, it can often be difficult to learn how to think 'functionally'. It took me years before I felt that I was on firm ground, and even so, I'm still learning new techniques today. As an imperative programmer, one often thinks in terms of state mutation. </p> <p> In Functional Programming, there are often other ways to solve problems than in object-oriented programming, but if you can't think of a way, you can often reach for the fairly blunt hammer than the State monad is. It enables you to implement ostensibly state-based algorithms in a functional way. </p> <p> This article was abstract, because I wanted to focus on the monad nature itself, rather than on practical applications. Future articles will provide more useful examples. </p> <p> <strong>Next:</strong> The Reader 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>. Some thoughts on naming tests https://blog.ploeh.dk/2022/06/13/some-thoughts-on-naming-tests 2022-06-13T07:51:00+00:00 Mark Seemann <div id="post"> <p> <em>What is the purpose of a test name?</em> </p> <p> Years ago I was participating in a coding event where we <a href="/2020/01/13/on-doing-katas">did katas</a>. My pairing partner and I was doing <em>silent ping pong</em>. Ping-pong style pair programming is when one programmer writes a test and passes the keyboard to the partner, who writes enough code to pass the test. He or she then writes a new test and passes control back to the first person. In the <em>silent</em> variety, you're not allowed to talk. This is an exercise in communicating via code. </p> <p> My partner wrote a test and I made it pass. After the exercise was over, we were allowed to talk to evaluate how it went, and my partner remarked that he'd been surprised that I'd implemented the opposite behaviour of what he'd intended. (It was something where there was a fork in the logic depending on a number being less than or greater to zero; I don't recall the exact details.) </p> <p> We looked at the test that he had written, and sure enough: He'd named the test by clearly indicating one behaviour, but then he'd written an assertion that looked for the opposite behaviour. </p> <p> I hadn't even noticed. </p> <p> I didn't read the test name. I only considered the test body, because that's the executable specification. </p> <h3 id="211621375fca4b7590abdfe87a27542b"> How tests are named <a href="#211621375fca4b7590abdfe87a27542b" title="permalink">#</a> </h3> <p> I've been thinking about test names ever since. What is the role of a test name? </p> <p> In some languages, you write unit tests as methods or functions. That's how you do it in C#, Java, and many other languages: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;Home&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;Calendar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;Reservations&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">WithControllerHandlesSuffix</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">name</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;UrlBuilder(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.WithController(name&nbsp;+&nbsp;<span style="color:#a31515;">&quot;Controller&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;sut.WithController(name); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;actual); }</pre> </p> <p> Usually, when we define new class methods, we've learned that naming is important. Truly, this applies to test methods, too? </p> <p> Yet, other languages don't use class methods to define tests. The most common JavaScript frameworks don't, and <a href="/2018/05/07/inlined-hunit-test-lists">neither does Haskell HUnit</a>. Instead, tests are simply values with labels. </p> <p> This hints at something that may be important. </p> <h3 id="03845212a1284263a6cdf452e7fd0bea"> The role of test names <a href="#03845212a1284263a6cdf452e7fd0bea" title="permalink">#</a> </h3> <p> If tests aren't necessarily class methods, then what role do names play? </p> <p> Usually, when considering method names, it's important to provide a descriptive name in order to help client developers. A client developer writing calling code must figure out which methods to call on an object. Good names help with that. </p> <p> Automated tests, on the other hand, have no explicit callers. There's no client developer to communicate with. Instead, a test framework such as <a href="https://xunit.net">xUnit.net</a> scans the public API of a test suite and automatically finds the test methods to execute. </p> <p> The most prominent motivation for writing good method names doesn't apply here. We must reevaluate the role of test names, also keeping in mind that with some frameworks, in some languages, tests aren't even methods. </p> <h3 id="06e15a7c7d90430685afd0182b878546"> Mere anarchy is loosed upon the world <a href="#06e15a7c7d90430685afd0182b878546" title="permalink">#</a> </h3> <p> The story that introduces this article has a point. When considering a test, I tend to go straight to the test body. I only read the test name if I find the test body unclear. </p> <p> Does this mean that the test name is irrelevant? Should we simply number the tests: <code>Test1</code>, <code>Test212</code>, and so on? </p> <p> That hardly seems like a good idea - not even to a person like me who considers the test name secondary to the test definition. </p> <p> This begs the question, though: If <code>Test42</code> isn't a good name, then what does a good test name look like? </p> <h3 id="bf895999bc034985ab10e839a69be5d4"> Naming schemes <a href="#bf895999bc034985ab10e839a69be5d4" title="permalink">#</a> </h3> <p> Various people suggest naming schemes. In the .NET world many people like <a href="https://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html">Roy Osherove's naming standard for unit tests</a>: <code>[UnitOfWork_StateUnderTest_ExpectedBehavior]</code>. I find it too verbose to my tastes, but my point isn't to attack this particular naming scheme. In my <a href="/2016/02/10/types-properties-software">Types + Properties = Software</a> article series, I experimented with using a poor man's version of <em>Given When Then:</em> </p> <p> <pre>[&lt;<span style="color:#4ec9b0;">Property</span>&gt;] <span style="color:blue;">let</span>&nbsp;<span style="color:navy;">``Given&nbsp;deuce&nbsp;when&nbsp;player&nbsp;wins&nbsp;then&nbsp;score&nbsp;is&nbsp;correct``</span> &nbsp;&nbsp;&nbsp;&nbsp;(winner&nbsp;:&nbsp;<span style="color:#4ec9b0;">Player</span>)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;:&nbsp;<span style="color:#4ec9b0;">Score</span>&nbsp;=&nbsp;<span style="color:navy;">scoreWhenDeuce</span>&nbsp;winner &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;expected&nbsp;=&nbsp;<span style="color:navy;">Advantage</span>&nbsp;winner &nbsp;&nbsp;&nbsp;&nbsp;expected&nbsp;=!&nbsp;actual</pre> </p> <p> It was a worthwhile experiment, but I don't think I ever used that style again. After all, <em>Given When Then</em> is just another way of saying <em>Arrange Act Assert</em>, and I already <a href="/2013/06/24/a-heuristic-for-formatting-code-according-to-the-aaa-pattern">organise my test code according to the AAA pattern</a>. </p> <p> These days, I don't follow any particular naming scheme, but I do keep a guiding principle in mind. </p> <h3 id="4db32b0268064abda82e32fb5724d7b6"> Information channel <a href="#4db32b0268064abda82e32fb5724d7b6" title="permalink">#</a> </h3> <p> A test name, whether it's a method name or a label, is an opportunity to communicate with the reader of the code. You can communicate via code, via names, via comments, and so on. A test name is more like a mandatory comment than a normal method name. </p> <p> Books like <a href="/ref/clean-code">Clean Code</a> make a compelling case that comments should be secondary to good names. The point isn't that all comments are bad, but that some are: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">z</span>&nbsp;=&nbsp;x&nbsp;+&nbsp;y;&nbsp;<span style="color:green;">//&nbsp;Add&nbsp;x&nbsp;and&nbsp;y</span></pre> </p> <p> It's rarely a good idea to add a comment that describes what the code <em>does</em>. This should already be clear from the code itself. </p> <p> A comment can still provide important information that code can't easily do. It may explain the <em>purpose</em> of the code. I try to take this into account when naming tests: Not repeat what the code does, but suggest a hint about its raison d'être. </p> <p> I try to strike a balance between <code>Test2112</code> and <code>Given&nbsp;deuce&nbsp;when&nbsp;player&nbsp;wins&nbsp;then&nbsp;score&nbsp;is&nbsp;correct</code>. I view the task of naming tests as equivalent to producing section headings in an article like this one. They offer a hint at the kind of information that might be available in the section (<em>The role of test names</em>, <em>How tests are named</em>, or <em>Information channel</em>), but sometimes they're more tongue-in-cheek than helpful (<em>Mere anarchy is loosed upon the world</em>). I tend to name tests with a similar degree of precision (or lack thereof): <code>HomeReturnsJson</code>, <code>NoHackingOfUrlsAllowed</code>, <code>GetPreviousYear</code>, etcetera. </p> <p> These names, in isolation, hardly tell you what the tests are about. I'm okay with that, because I don't think that they have to. </p> <h3 id="cd5ccd57ea8a41dbb78f8b5c32985311"> What do you use test names for? <a href="#cd5ccd57ea8a41dbb78f8b5c32985311" title="permalink">#</a> </h3> <p> I occasionally discuss this question with other people. It seems to me that it's one of the topics where Socratic questioning breaks down: </p> <p> Them: <em>How do you name tests?</em> </p> <p> Me: <em>I try to strike a balance between information and not repeating myself.</em> </p> <p> Them: <em>How do you like this particular naming scheme?</em> </p> <p> Me: <em>It looks verbose to me. It seems to be repeating what's already in the test code.</em> </p> <p> Them: <em>I like to read the test name to see what the test does.</em> </p> <p> Me: <em>If the name and test code disagree, which one is right?</em> </p> <p> Them: <em>The test name should follow the naming scheme.</em> </p> <p> Me: <em>Why do you find that important?</em> </p> <p> Them: <em>It's got... electrolytes.</em> </p> <p> Okay, I admit that <a href="https://en.wikipedia.org/wiki/Satire">I'm a being uncharitable</a>, but the point that I'm after is that test names are <em>different</em>, yet most people seem to reflect little on this. </p> <p> When do you read test names? </p> <p> Personally, I rarely read or otherwise <em>use</em> test names. When I'm writing a test, I also write the name, but at that point I don't really <em>need</em> the name. Sometimes I start with a placeholder name (<code>Foo</code>), write the test, and change the name once I understand what the test does. </p> <p> Once a test is written, ideally it should just be sitting there as a regression test. <a href="/2013/04/02/why-trust-tests">The less you touch it, the better you can trust it</a>. </p> <p> You may have hundreds or thousands of tests. When you run your test suite, you care about the outcome. Did it pass or fail? The outcome is the result of a Boolean <em>and</em> operation. The test suite only passes when all tests pass, but you don't have to look at each test result. The aggregate result is enough as long as the test suite passes. </p> <p> You only need to look at a test when it fails. When this happens, most tools enable you to go straight to the failing test by clicking on it. (And if this isn't possible, I usually find it easier to navigate to the failing test either by line number or by copying the test name and navigating to it by pasting the name into my editor's navigation UI.) You don't really need the name to find a failing test. If the test was named <code>Test1337</code> it would be as easy to find as if it was named <code>Given&nbsp;deuce&nbsp;when&nbsp;player&nbsp;wins&nbsp;then&nbsp;score&nbsp;is&nbsp;correct</code>. </p> <p> Once I look at a failing test, I start by looking at the test code and comparing that to the assertion message. </p> <p> Usually, when a test fails, it breaks for a reason. A code change caused the test to fail. Often, the offending change was one you did ten seconds earlier. Armed with an assertion message and the test code, I usually understand the problem right away. </p> <p> In rare cases the test is one that I've never seen before, and I'm confused about its purpose. This is when I read the test name. At that point, I appreciate if the name is helpful. </p> <h3 id="62f1324f399243c393c77a3cbb46f173"> Conclusion <a href="#62f1324f399243c393c77a3cbb46f173" title="permalink">#</a> </h3> <p> I'm puzzled that people are so <a href="/2021/03/22/the-dispassionate-developer">passionate</a> about test names. I consider them the least important part of a test. A name isn't irrelevant, but I find the test code more important. The code is an executable specification. It expresses the desired truth about a system. </p> <p> Test code is code that has the same lifetime as the production code. It pays to structure it as well as the production code. If a test is well-written, you should be able to understand it without reading its name. </p> <p> That's an ideal, and in reality we are fallible. Thus, providing a helpful name gives the reader a second chance to understand a test. The name shouldn't, however, be your first priority. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="8e8c4bda169848e988926028933189d0"> <div class="comment-author"><a href="http://github.com/neongraal">Struan Judd</a></div> <div class="comment-content"> <p> I often want run selected tests from the command line and thus use the test runner's abilty to filter all available tests. Where the set of tests I want to run is all the tests below some point in the heirarchy of tests I can filter by the common prefix, or the test class name. </p> <p> But I also often find myself wanting to run a set of tests that meet some functional criteria, e.g Validation approval tests, or All the tests for a particular feature across all the levels of the code base. In this case if the tests follow a naming convention where such test attributes are included in the test name, either via the method or class name, then such test filtering is possible. </p> </div> <div class="comment-date">2022-06-13 10:21 UTC</div> </div> <div class="comment" id="d1a000d5eb8349a586e19dbb231ce744"> <div class="comment-author"><a href="https://github.com/flakey-bit">Eddie Stanley</a></div> <div class="comment-content"> <p> Mark, are you a <a href="https://www.thoughtworks.com/insights/blog/mockists-are-dead-long-live-classicists" target="_blank">Classicist or a Mockist</a>? I'm going to go out on a limb here and say you're probably a classicist. Test code written in a classicist style probably conveys the intent well already. I think code written in a Mockist style may not convey the intent as well, hence the test name (or a comment) becomes more useful to convey that information. </p> </div> <div class="comment-date">2022-06-13 23:40 UTC</div> </div> <div class="comment" id="63217ba97aed47cb877c9dd56e53ae31"> <div class="comment-author"><a href="https://www.chriskrycho.com">Chris Krycho</a></div> <div class="comment-content"> <p> There are (at least) two ways of using test names (as well as test <em>module</em> names, as suggested by Struan Judd) that we make extensive use of in the LinkedIn code base and which I have used in every code base I have ever written tests for: </p> <ul> <li> <p> <strong>To indicate the <em>intent</em> of the test.</strong> It is well and good to say that the assertions should convey the conditions, but often it is not clear <em>why</em> a condition is intended to hold. Test names (and descriptive strings on the assertions) can go a very long way, especially when working in a large and/or unfamiliar code base, to understand whether the assertion remains relevant, or <em>how</em> it is relevant. </p> <p> Now, granted: it is quite possible for those to get out of date, much as comments do. However, just as good comments remain valuable even though there is a risk of stale comments, good test names can be valuable even though they can also become stale. </p> <p> The key, for me, is exactly the same as good comments—and you could argue that comments therefore obviate the need for test names. If we only cared about tests from the POV of reading the code, I would actually agree! However, because we often read the tests as a suite of assertions presented in some other UI (a terminal, a web view, etc.), the names and assertion descriptions themselves serve as the explanation when reading. </p> </li> <li> <p> <strong>To provide structure and organization to the test suite.</strong> This is the same point Struan Judd was getting at: having useful test names lets you filter down to relevant chunks of the suite easily. This is valuable even on a small code base (like <a href="https://github.com/true-myth/true-myth">the <code>Maybe</code> and <code>Result</code> library in TypeScript</a> a friend and I maintain), but it becomes <em>invaluable</em> when you have tens of thousands of tests to filter or search through, as in the main LinkedIn app! </p> <p> For that reason, we (and the Ember.js community more broadly) make extensive use of QUnit's <code>module()</code> hook to name the <em>set</em> of modules under test (<code>module('Rendering | SomeComponent', function () { ... }</code> or <code>module('Unit | some-utility', function () { ... }</code>) as well as naming <code>test()</code> (<code>test('returns `null` if condition X does not hold', function (assert) { ... }</code>) and indeed providing descriptive strings for <code>assert()</code> calls. We might even nest <code>module()</code> calls to make it easy to see and filter from how our test UI presents things: <strong>Rendering | SomeComponent > someMethod > a test description</strong>. </p> </li> </ul> <p> Now, how that plays out varies library to library. The aforementioned TS library just names the test with a decent description of what is under test (<a href="https://github.com/true-myth/true-myth/blob/cc2883e63748705272ff423d958525b65524c640/test/result.test.ts#L10-L31">here</a>, for example) as well as grouping them sensibly with overarching descriptions, and never uses assertion descriptions because they wouldn’t add anything. A couple of the libraries I wrote internally at LinkedIn, by contrast, make extensive use of both. It is, as usual, a tool to be employed as, and only as, it is <em>useful</em>. But it is indeed quite useful sometimes! </p> </div> <div class="comment-date">2022-06-14 00:57 UTC</div> </div> <div class="comment" id="81fdb10f87804872b24acae33ea14ecd"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Struan, thank you for writing. I can't say that I've given much thought to the need to run subsets of a test suite. You have a point, though, that if that's a requirement, you need something on which to filter. </p> <p> Is the name the appropriate criterion for that, though? It sounds brittle to me, but I grant that it depends on which alternatives are available. In <a href="https://xunit.net/">xUnit.net</a>, for example, you can use the <code>[Trait]</code> attribute to annotate tests with arbitrary metadata. I think that <a href="https://nunit.org/">NUnit</a> has a similar feature, but there's no guarantee that every unit testing framework on any platform or language supports such a feature. </p> <p> Whenever a framework supports such metadata-based filtering, I'd favour relying on that instead of naming conventions. Naming conventions are vulnerable to misspellings and other programmer errors. That may also be true of metadata-based categorisation, but hopefully to a lesser degree, as these might enable you to use ordinary language features to keep the categories DRY. </p> <p> Using names also sounds restrictive to me. Doesn't this mean that you have to be able to predict your filtering requirements when you decide on a naming scheme? </p> <p> What if, later, you find that you need to filter on a different dimension? With metadata annotations, you should be able to add a new category to the affected tests, but how will you do that with an established naming scheme? </p> <p> Overall, though, the reason that I haven't given this much thought is that I've never had the need to filter tests in arbitrary ways. You must be doing something different from how I work with tests. Why do you need to filter tests? </p> </div> <div class="comment-date">2022-06-19 21:59 UTC</div> </div> <div class="comment" id="b8c145c78a3649ada137f8c997e10b4a"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Eddie, thank you for writing. I don't find the linked article illuminating if one hasn't already heard about the terms <em>mockist</em> and <em>classicist</em>. I rather prefer the terms <em>interaction-based</em> and <em>state-based</em> testing. In any case, I started out doing interaction-based testing, but have since <a href="/2019/02/18/from-interaction-based-to-state-based-testing">moved away from that</a>. Even when I mainly wrote interaction-based tests, though, I didn't like rigid naming schemes. I don't see how that makes much of a difference. </p> <p> I agree that a test name is a fine opportunity to convey intent. Did that not come across in the article? </p> </div> <div class="comment-date">2022-06-22 1:37 UTC</div> </div> <div class="comment" id="b74a945cce364621b0f80d247d7153f3"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Chris, thank you for writing. As I also <a href="#b8c145c78a3649ada137f8c997e10b4a">responded to Eddie Stanley</a>, I agree that a test name is a fine opportunity to convey intent. Did that not come across in the article? </p> <p> To your second point, I'll refer you to <a href="#81fdb10f87804872b24acae33ea14ecd">my answer to Struan Judd</a>. I'm still curious to learn <em>why</em> you find it necessary to categorise and filter tests. </p> </div> <div class="comment-date">2022-06-22 23:03 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>. Asynchronous monads https://blog.ploeh.dk/2022/06/06/asynchronous-monads 2022-06-06T07:33:00+00:00 Mark Seemann <div id="post"> <p> <em>Asynchronous computations form monads. 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>. A previous article described how <a href="/2018/09/24/asynchronous-functors">asynchronous computations form functors</a>. In this article, you'll see that asynchronous computations also form monads. You'll learn about closely related monads: .NET Tasks and <a href="https://fsharp.org">F#</a> <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/async-expressions">asynchronous workflows</a>. </p> <p> Before we start, I'm going to repeat the warning from the article about asynchronous functors. .NET Tasks aren't <a href="https://en.wikipedia.org/wiki/Referential_transparency">referentially transparent</a>, whereas F# asynchronous computations are. You could argue, then, that .NET Tasks aren't proper monads, but you mostly observe the difference when you perform impure operations. As a general observation, when impure operations are allowed, the conclusions of <a href="/2017/10/04/from-design-patterns-to-category-theory">this overall article series</a> are precarious. We can't radically change how the .NET languages work, so we'll have to soldier on, pretending that impure operations are delegated to other parts of our system. Under this undue assumption, we can pretend that <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1">Task&lt;T&gt;</a> forms a monad. Also, while there are differences, <a href="/2020/07/27/task-asynchronous-programming-as-an-io-surrogate">it sometimes helps to think of <code>Task&lt;T&gt;</code> as a sort of poor man's IO monad</a>. </p> <h3 id="1ab27adfb0194a10a2fa02690b49343b"> Monadic bind <a href="#1ab27adfb0194a10a2fa02690b49343b" 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>. You can define one as an extension method on the <a href="https://docs.microsoft.com/dotnet/api/system.threading.tasks.task-1">Task&lt;T&gt;</a> class: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Task&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;Task&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Task&lt;TResult&gt;&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">await</span>&nbsp;selector(x); }</pre> </p> <p> With <code>SelectMany</code>, you can compose various tasks and flatten as you go: </p> <p> <pre>Task&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&nbsp;AsyncValue(&nbsp;&nbsp;42); Task&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">y</span>&nbsp;=&nbsp;AsyncValue(1337); Task&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">z</span>&nbsp;=&nbsp;x.SelectMany(<span style="color:blue;">async</span>&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;i&nbsp;+&nbsp;<span style="color:blue;">await</span>&nbsp;y);</pre> </p> <p> If you're wondering how this is useful, since C# already has <code>async</code> and <code>await</code> keywords for that purpose, I can understand you. Had you not had that language feature, monadic bind would have been helpful, but now it feels a little odd. (I haven't been deep into the bowels of how that language feature works, but from what little I've seen, monads play a central role - just as they do in the LINQ language feature.) </p> <p> In F# you can define a <code>bind</code> function that works on <code>Async&lt;'a&gt;</code> values: </p> <p> <pre><span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;Async&lt;&#39;b&gt;)&nbsp;-&gt;&nbsp;Async&lt;&#39;a&gt;&nbsp;-&gt;&nbsp;Async&lt;&#39;b&gt;</span> <span style="color:blue;">let</span>&nbsp;bind&nbsp;f&nbsp;x&nbsp;=&nbsp;async&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;x&#39;&nbsp;=&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return!</span>&nbsp;f&nbsp;x&#39;&nbsp;}</pre> </p> <p> For both the C# and the F# examples, the exercise seems a little redundant, since they're both based on language features. The C# <code>SelectMany</code> implementation uses the <code>async</code> and <code>await</code> keywords, and the F# <code>bind</code> function uses the built-in <code>async</code> <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/computation-expressions">computation expression</a>. For that reason, I'll also skip the section on syntactic sugar that I've included in the previous articles in this article series. Syntactic sugar is already built into the languages. </p> <h3 id="e27cbc4c22ac4f66a311cb41584f971c"> Flatten <a href="#e27cbc4c22ac4f66a311cb41584f971c" 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>Task&lt;T&gt;</code>, we can use that to implement <code>Flatten</code>. In this article I use the name <code>Flatten</code> rather than <code>Join</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>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;Task&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;Task&lt;Task&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> The F# version uses the same implementation - it's just a bit terser: </p> <p> <pre><span style="color:green;">//&nbsp;Async&lt;Async&lt;&#39;a&gt;&gt;&nbsp;-&gt;&nbsp;Async&lt;&#39;a&gt;</span> <span style="color:blue;">let</span>&nbsp;flatten&nbsp;x&nbsp;=&nbsp;bind&nbsp;id&nbsp;x</pre> </p> <p> In F#, <code>id</code> is a built-in function. </p> <h3 id="99a8068b063e416daf4e8383fda97331"> Return <a href="#99a8068b063e416daf4e8383fda97331" 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>Task&lt;T&gt;</code> this function already exists: It's called <a href="https://docs.microsoft.com/dotnet/api/system.threading.tasks.task.fromresult">FromResult</a>. </p> <p> In F#, it's not built-in, but easy to implement: </p> <p> <pre><span style="color:green;">//&nbsp;&#39;a&nbsp;-&gt;&nbsp;Async&lt;&#39;a&gt;</span> <span style="color:blue;">let</span>&nbsp;fromValue&nbsp;x&nbsp;=&nbsp;async&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;x&nbsp;}</pre> </p> <p> I called it <code>fromValue</code> inspired by the C# method name (and also because <code>return</code> is a reserved keyword in F#). </p> <h3 id="f6b42483d4454e8a8e3e6d580b0595db"> Left identity <a href="#f6b42483d4454e8a8e3e6d580b0595db" 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>. Now that this is done, let's see what the laws look like for the asynchronous monads, 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;">TaskHasLeftIdentity</span>(Func&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&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;Task&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Task.FromResult; &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#74531f;">h</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;Task.FromResult(h_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(@return(a).SelectMany(h).Result,&nbsp;h(a).Result); }</pre> </p> <p> Like in <a href="/2022/05/30/the-lazy-monad">the previous article</a> the test 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, but it unfortunately, it can't generate asynchronous computations. Instead, I've asked FsCheck to generate a function that I then convert to an asynchronous computation. </p> <p> The code I'm using for this article is quite old, and neither FsCheck 2.11.0 nor xUnit.net 2.4.0 can handle asynchronous unit tests (a capability that later versions do have). Thus, the assertion has to force the computations to run by accessing the <code>Result</code> property. Not modern best practice, but it gets the point across, I hope. </p> <p> In F# I wrote monad law examples using <a href="/2022/04/04/kleisli-composition">Kleisli composition</a>. I first defined a function called <code>fish</code>: </p> <p> <pre><span style="color:green;">//&nbsp;(&#39;a&nbsp;-&gt;&nbsp;Async&lt;&#39;b&gt;)&nbsp;-&gt;&nbsp;(&#39;b&nbsp;-&gt;&nbsp;Async&lt;&#39;c&gt;)&nbsp;-&gt;&nbsp;&#39;a&nbsp;-&gt;&nbsp;Async&lt;&#39;c&gt;</span> <span style="color:blue;">let</span>&nbsp;fish&nbsp;f&nbsp;g&nbsp;x&nbsp;=&nbsp;async&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let!</span>&nbsp;x&#39;&nbsp;=&nbsp;f&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return!</span>&nbsp;g&nbsp;x&#39;&nbsp;}</pre> </p> <p> Keep in mind that <em>fish</em> is also a verb, so that's okay for a function name. The function then implements the <em>fish operator:</em> </p> <p> <pre><span style="color:blue;">let</span>&nbsp;(&gt;=&gt;)&nbsp;=&nbsp;Async.fish</pre> </p> <p> This enables us to give an example of the left identity law using Kleisli composition: </p> <p> <pre>[&lt;Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``Async&nbsp;fish&nbsp;has&nbsp;left&nbsp;identity``&nbsp;(h&#39;&nbsp;:&nbsp;int&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;string)&nbsp;a&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;h&nbsp;x&nbsp;=&nbsp;async&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;h&#39;&nbsp;x&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;&nbsp;left&nbsp;=&nbsp;Async.fromValue&nbsp;&gt;=&gt;&nbsp;h &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;right&nbsp;=&nbsp;h &nbsp;&nbsp;&nbsp;&nbsp;Async.RunSynchronously&nbsp;(left&nbsp;a)&nbsp;=!&nbsp;Async.RunSynchronously&nbsp;(right&nbsp;a)</pre> </p> <p> The <code>=!</code> operator is an <a href="https://github.com/SwensenSoftware/Unquote">Unquote</a> operator that I usually read as <em>must equal</em>. It's a test assertion that'll throw an exception if the left and right sides aren't equal. </p> <h3 id="ef0d98230ec6429c855f15a7a876fdad"> Right identity <a href="#ef0d98230ec6429c855f15a7a876fdad" title="permalink">#</a> </h3> <p> In a similar manner, we can showcase the right identity law as a test - first in C#: </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;">TaskHasRightIdentity</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;Task&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Task.FromResult; &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">m</span>&nbsp;=&nbsp;Task.FromResult(a); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(m.SelectMany(@return).Result,&nbsp;m.Result); }</pre> </p> <p> Here's a Kleisli-composition-based F# property that demonstrates the right identity law for asynchronous workflows: </p> <p> <pre>[&lt;Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``Async&nbsp;fish&nbsp;has&nbsp;right&nbsp;identity``&nbsp;(f&#39;&nbsp;:&nbsp;int&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;string)&nbsp;a&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;f&nbsp;x&nbsp;=&nbsp;async&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;f&#39;&nbsp;x&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;&nbsp;left&nbsp;=&nbsp;f &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;right&nbsp;=&nbsp;f&nbsp;&gt;=&gt;&nbsp;Async.fromValue &nbsp;&nbsp;&nbsp;&nbsp;Async.RunSynchronously&nbsp;(left&nbsp;a)&nbsp;=!&nbsp;Async.RunSynchronously&nbsp;(right&nbsp;a)</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="cc6f13f397574584b0c3dbb55cb15726"> Associativity <a href="#cc6f13f397574584b0c3dbb55cb15726" 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;">TaskIsAssociative</span>( &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;DateTime,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">f_</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;">g_</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">byte</span>&gt;&nbsp;<span style="color:#1f377f;">h_</span>, &nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#1f377f;">a</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#74531f;">f</span>(DateTime&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;Task.FromResult(f_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#74531f;">g</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;Task.FromResult(g_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;<span style="color:blue;">byte</span>&gt;&nbsp;<span style="color:#74531f;">h</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;Task.FromResult(h_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Task&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(g).SelectMany(h).Result,&nbsp;m.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h)).Result); }</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>, which it then converts to asynchronous computations. The same does the Kleisli-composition-based F# property: </p> <p> <pre>[&lt;Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``Async&nbsp;fish&nbsp;is&nbsp;associative``&nbsp;(f&#39;&nbsp;:&nbsp;int&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;string)&nbsp;(g&#39;&nbsp;:&nbsp;string&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;byte)&nbsp;(h&#39;&nbsp;:&nbsp;byte&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;bool)&nbsp;a&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;f&nbsp;x&nbsp;=&nbsp;async&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;f&#39;&nbsp;x&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;g&nbsp;x&nbsp;=&nbsp;async&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;g&#39;&nbsp;x&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;h&nbsp;x&nbsp;=&nbsp;async&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;h&#39;&nbsp;x&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;&nbsp;left&nbsp;=&nbsp;(f&nbsp;&gt;=&gt;&nbsp;&nbsp;g)&nbsp;&gt;=&gt;&nbsp;h &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;right&nbsp;=&nbsp;&nbsp;f&nbsp;&gt;=&gt;&nbsp;(g&nbsp;&nbsp;&gt;=&gt;&nbsp;h) &nbsp;&nbsp;&nbsp;&nbsp;Async.RunSynchronously&nbsp;(left&nbsp;a)&nbsp;=!&nbsp;Async.RunSynchronously&nbsp;(right&nbsp;a)</pre> </p> <p> It's easier to see the associativity that the law is named after when using Kleisli composition, but as <a href="/2022/04/11/monad-laws">the article about the monad laws</a> explained, the two variations are equivalent. </p> <h3 id="c7e119135d3243e9b29dae38ab6969bd"> Conclusion <a href="#c7e119135d3243e9b29dae38ab6969bd" title="permalink">#</a> </h3> <p> Whether you do asynchronous programming with <code>Task&lt;T&gt;</code> or <code>Async&lt;'a&gt;</code>, asynchronous computations form monads. This enables you to piecemeal compose asynchronous workflows. </p> <p> <strong>Next:</strong> <a href="/2022/06/20/the-state-monad">The State 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 Lazy monad https://blog.ploeh.dk/2022/05/30/the-lazy-monad 2022-05-30T05:34:00+00:00 Mark Seemann <div id="post"> <p> <em>Lazy computations 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>. A previous article described how <a href="/2018/09/10/the-lazy-functor">lazy computations form a functor</a>. In this article, you'll see that lazy computations also form a monad. </p> <h3 id="749d0adfe50046dbaf3fdb63c1f28ebd"> SelectMany <a href="#749d0adfe50046dbaf3fdb63c1f28ebd" 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>. You can define one as an extension method on the <a href="https://docs.microsoft.com/dotnet/api/system.lazy-1">Lazy&lt;T&gt;</a> class: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Lazy&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;Lazy&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Lazy&lt;TResult&gt;&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;Lazy&lt;TResult&gt;(()&nbsp;=&gt;&nbsp;selector(source.Value).Value); }</pre> </p> <p> While the implementation seemingly forces evaluation by accessing the <code>Value</code> property, this all happens inside a lambda expression that defers execution. </p> <p> If <code>x</code> is a <code>Lazy&lt;int&gt;</code> and <code>SlowToString</code> is a function that takes an <code>int</code> as input and returns a <code>Lazy&lt;string&gt;</code> you can compose them like this: </p> <p> <pre>Lazy&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">y</span>&nbsp;=&nbsp;x.SelectMany(SlowToString);</pre> </p> <p> The result is another lazy computation that, when forced, will produce a <code>string</code>. </p> <h3 id="e84186c0a20546e393b2d803c1af01b1"> Query syntax <a href="#e84186c0a20546e393b2d803c1af01b1" 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;Lazy&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;Lazy&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;Lazy&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 would enable you to rewrite the above example like this: </p> <p> <pre>Lazy&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">y</span>&nbsp;=&nbsp;<span style="color:blue;">from</span>&nbsp;i&nbsp;<span style="color:blue;">in</span>&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;SlowToString(i) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;s;</pre> </p> <p> The behaviour is the same as above. 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="8170cd0d693c455fa02a44bd293100a8"> Flatten <a href="#8170cd0d693c455fa02a44bd293100a8" 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>Lazy&lt;T&gt;</code>, we can use that to implement <code>Flatten</code>. In this article I use the name <code>Flatten</code> rather than <code>Join</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>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;Lazy&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;Lazy&lt;Lazy&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> You could also compose the above <code>x</code> and <code>SlowToString</code> with <code>Select</code> and <code>Flatten</code>, like this: </p> <p> <pre>Lazy&lt;Lazy&lt;<span style="color:blue;">string</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">nested</span>&nbsp;=&nbsp;x.Select(SlowToString); Lazy&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">flattened</span>&nbsp;=&nbsp;nested.Flatten();</pre> </p> <p> The <code>flattened</code> value remains deferred until you force execution. </p> <h3 id="e1c48063295e4a4ea8f91dc2b5539219"> Return <a href="#e1c48063295e4a4ea8f91dc2b5539219" 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>Lazy&lt;T&gt;</code> in C# the idiomatic way would be to use a constructor, but the version of .NET I'm using for this code (this is actually code I wrote years ago) doesn't have such a constructor (newer versions do). Instead, I'll define a function: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Lazy&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;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Lazy&lt;T&gt;(()&nbsp;=&gt;&nbsp;x); }</pre> </p> <p> In other words, <code>Return</code> wraps a pre-existing value in a lazy computation. </p> <h3 id="078ba13f5e33436a915b386b5826c05d"> Left identity <a href="#078ba13f5e33436a915b386b5826c05d" 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>. Now that this is done, let's see what the laws look like for the Lazy 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;">LazyHasLeftIdentity</span>(Func&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&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;Lazy&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Lazy.Return; &nbsp;&nbsp;&nbsp;&nbsp;Lazy&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#74531f;">h</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;Lazy.Return(h_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(@return(a).SelectMany(h).Value,&nbsp;h(a).Value); }</pre> </p> <p> Like in <a href="/2022/05/16/the-identity-monad">the previous article</a> the test 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, but it unfortunately, it can't generate lazy computations. Instead, I've asked FsCheck to generate a function that I then convert to a lazy computation. </p> <p> In order to compare the values, the assertion has to force evaluation by reading the <code>Value</code> properties. </p> <h3 id="e3c13eb7e8ee4bd789f7b477d3cb5945"> Right identity <a href="#e3c13eb7e8ee4bd789f7b477d3cb5945" 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;">LazyHasRightIdentity</span>(Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&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;">string</span>,&nbsp;Lazy&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;Lazy.Return(f_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;Lazy&lt;<span style="color:blue;">int</span>&gt;&gt;&nbsp;<span style="color:#1f377f;">@return</span>&nbsp;=&nbsp;Lazy.Return; &nbsp;&nbsp;&nbsp;&nbsp;Lazy&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).Value,&nbsp;m.Value); }</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="9cd90607b2974086a9194fd5e9c1e712"> Associativity <a href="#9cd90607b2974086a9194fd5e9c1e712" 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;">LazyIsAssociative</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;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">byte</span>&gt;&nbsp;<span style="color:#1f377f;">g_</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">byte</span>,&nbsp;TimeSpan&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;Lazy&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#74531f;">f</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;Lazy.Return(f_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Lazy&lt;<span style="color:blue;">byte</span>&gt;&nbsp;<span style="color:#74531f;">g</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;Lazy.Return(g_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Lazy&lt;TimeSpan&gt;&nbsp;<span style="color:#74531f;">h</span>(<span style="color:blue;">byte</span>&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;Lazy.Return(h_(x)); &nbsp;&nbsp;&nbsp;&nbsp;Lazy&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).Value,&nbsp;m.SelectMany(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;g(x).SelectMany(h)).Value); }</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>, which it then converts to lazy computations. </p> <h3 id="5c5416d137e444baa298182dbf315235"> Conclusion <a href="#5c5416d137e444baa298182dbf315235" title="permalink">#</a> </h3> <p> The Lazy functor (which <a href="/2018/12/17/the-lazy-applicative-functor">is also an applicative functor</a>) is also a monad. This can be used to combine multiple lazily computed values into a single lazily computed value. </p> <p> <strong>Next:</strong> <a href="/2022/06/06/asynchronous-monads">Asynchronous 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>. Waiting to never happen https://blog.ploeh.dk/2022/05/23/waiting-to-never-happen 2022-05-23T05:55:00+00:00 Mark Seemann <div id="post"> <p> <em>An example of how non-deterministic code can cause test cases to wither.</em> </p> <p> It seems to me that when people discuss functional programming, they spend much time discussing side effects and how to avoid them. Sometimes, they almost forget that non-deterministic behaviour is also something to avoid. </p> <p> On the other hand, we've known for a long time that we should <a href="https://martinfowler.com/articles/nonDeterminism.html">eradicate non-determinism in tests</a>. Martin Fowler's article, however, mostly discusses <a href="https://en.wikipedia.org/wiki/False_positives_and_false_negatives">false positives</a>: Tests that fail even when no defect is manifest. </p> <p> Unit tests may also exhibit <a href="http://xunitpatterns.com/false%20negative.html">false negatives</a>. This can happen for a variety of reason. In my article <a href="/2019/10/14/tautological-assertion">Tautological assertion</a> I describe one example. </p> <p> The passing of time, however, has a tendency to introduce decay. This may apply to test suites as well. If a test or the System Under Test depends on the current time, a test may over time transition from a proper test to one that still passes, but for the wrong reason. </p> <h3 id="68269f84da2845d2994b378001326bac"> A test example <a href="#68269f84da2845d2994b378001326bac" title="permalink">#</a> </h3> <p> I was recently looking at this test: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">ChangeDateToSoldOutDate</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r1</span>&nbsp;=&nbsp;Some.Reservation; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r2</span>&nbsp;=&nbsp;Some.Reservation &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithId(Guid.NewGuid()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDayAfter() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithQuantity(10); &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;db.Grandfather.Add(r1); &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather.Add(r2); &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;r1.WithDate(r2.At).ToDto(); &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;sut.Put(r1.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>),&nbsp;dto); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">oRes</span>&nbsp;=&nbsp;Assert.IsAssignableFrom&lt;ObjectResult&gt;(actual); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StatusCodes.Status500InternalServerError, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oRes.StatusCode); }</pre> </p> <p> It's from the code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. It's a false negative waiting to happen. What's the problem? </p> <p> Before I start describing the problem, I think that I owe you a short explanation of what you're looking at. The book has a single example code base that it uses to showcase various heuristics and techniques. The code base implements an online restaurant reservation REST API. I've <a href="/2021/06/14/new-book-code-that-fits-in-your-head">previously discussed that code base on this blog</a>. </p> <p> This particular test exercises the following test case: A client can use the REST API to change an existing reservation. When it does that, the API should check that all business rules apply. Particularly, in this case, if you have an existing reservation (<code>r1</code>), but try to change it to another date, and that other date is already sold out, the update should be refused. </p> <p> The test uses <a href="http://xunitpatterns.com/Back%20Door%20Manipulation.html">backdoor manipulation</a> to establish the initial state. It's a <a href="/2019/02/18/from-interaction-based-to-state-based-testing">state-based integration test</a> that uses an in-memory <a href="http://xunitpatterns.com/Fake%20Object.html">Fake</a> database. It adds two reservations (<code>r1</code> and <code>r2</code>) to the database, on two different days. </p> <p> What's not at all clear from the above code is that that <code>10</code> is the <code>Grandfather.Restaurant</code>'s maximum capacity. (This is a fair criticism against this test, but not what this article is about.) It effectively means that the restaurant is sold out that day. </p> <p> The test then, in <a href="/2013/06/24/a-heuristic-for-formatting-code-according-to-the-aaa-pattern">the act phase</a>, tries to change <code>r1</code> to the date that's sold out and <code>Put</code> that change. </p> <p> The assertion checks that this isn't possible. </p> <h3 id="994d6756ca4f444bbeba236980914a23"> A false negative waiting to happen <a href="#994d6756ca4f444bbeba236980914a23" title="permalink">#</a> </h3> <p> What's the problem with the above test? </p> <p> The problem is that <em>when I wrote it</em>, it exercised the above test case, but now it no longer does. </p> <p> At this point, you're probably wondering. The test case is supposed to change the date of <code>r1</code> to the date of <code>r2</code>, but no dates are visible in the test. Which dates does the test use? </p> <p> The answer may be found in the <code>Some</code> class: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Reservation&nbsp;Reservation&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Guid(0x81416928,&nbsp;0xC236,&nbsp;0x4EBF,&nbsp;0xA4,&nbsp;0x50,&nbsp;0x24,&nbsp;0x95,&nbsp;0xA4,&nbsp;0xDA,&nbsp;0x92,&nbsp;0x30), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Now, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Email(<span style="color:#a31515;">&quot;x@example.net&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Name(<span style="color:#a31515;">&quot;&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1);</pre> </p> <p> <code>Some.Reservation</code> is an <a href="/2017/09/11/test-data-without-builders">immutable test datum</a>. It's intended to be used as a representative example of a <code>Reservation</code> value. The reservation date and time (the <code>At</code> property) is another immutable test datum: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;DateTime&nbsp;Now&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;DateTime(2022,&nbsp;4,&nbsp;1,&nbsp;20,&nbsp;15,&nbsp;0);</pre> </p> <p> I wrote most of that code base in 2020. April 1st 2022 seemed far in the future, and I needed a value that could represent 'approximately' the current time. It didn't have to be the day the code would run, but (as it turns out) it's important that this date isn't in the past. Which it now is. </p> <p> What happens now that <code>Some.Reservation</code> is in the past? </p> <p> Nothing, and that's exactly what is the problem. </p> <h3 id="af00b9fef7124afd93b3b80bac4efbf5"> A new path <a href="#af00b9fef7124afd93b3b80bac4efbf5" title="permalink">#</a> </h3> <p> Once the clock rolled over from 2022-04-02 20:14:59 to 2022-04-02 20:15:00, the pathway through the code changed. Why April 2 and not April 1? Because the date of importance in the test is <code>TheDayAfter</code>, and <code>TheDayAfter</code> is defined like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Reservation&nbsp;<span style="color:#74531f;">TheDayAfter</span>(<span style="color:blue;">this</span>&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;reservation.AddDate(TimeSpan.FromDays(1)); }</pre> </p> <p> So <code>r2.At</code> is 20:15 April 2, 2022. </p> <p> Before 2022-04-02 20:15:00 the test would exercise the test case it was supposed to. After all, I did write the test <em>before</em> I wrote the implementation, and I did <a href="/2019/10/21/a-red-green-refactor-checklist">see it fail before I saw it pass</a>. </p> <p> Once, however, <code>dto</code> is in the past, another pathway takes over. The <a href="/2020/01/27/the-maitre-d-kata">Maître d's</a> core decision logic (<a href="/2020/11/30/name-by-role">WillAccept</a>) contains this Guard Clause: </p> <p> <pre><span style="color:#8f08c4;">if</span>&nbsp;(candidate.At&nbsp;&lt;&nbsp;now) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">false</span>;</pre> </p> <p> Long before the domain model investigates whether it can accommodate a reservation, it rejects all reservations in the past. The calling code, however, only sees that the return value is <code>false</code>. In other words, the externally observable behaviour is the same. This also means that test's assertion still passes. From the outside, you can't tell the difference. </p> <h3 id="8a3330c5362c47cbb5431a20a90f1278"> Coverage decay <a href="#8a3330c5362c47cbb5431a20a90f1278" title="permalink">#</a> </h3> <p> If the behaviour is stable, then why is this a problem? </p> <p> This is a problem because this decreases test coverage. While <a href="/2015/11/16/code-coverage-is-a-useless-target-measure">code coverage is a useless target measure</a>, it's not a completely useless metric. The absolute percentage is less relevant than the trend. If code coverage decreases, one should at least investigate. </p> <p> Here, specifically, it means that I thought I had a particular test case covered, and in reality it turns out that that's no longer the case. Now the test just verifies that you can't update past reservations, regardless of application state. Other tests already verify that, however, so this test now became redundant. </p> <p> As I've <a href="/2018/11/12/what-to-test-and-not-to-test">described before</a>, each test case exercises a particular path through the System Under Test: </p> <p> <img src="/content/binary/one-test-path-through-complex-unit.png" alt="Diagram that shows a unit test exercising one path through a unit."> </p> <p> If you have high code coverage, an aggregate diagram might look like this: </p> <p> <img src="/content/binary/most-test-paths-through-complex-unit.png" alt="Diagram that shows several unit tests exercising most paths through a unit."> </p> <p> Notice that the top box now says <em>Unit tests</em> in plural. Together, the tests exercise most pathways through the code. There's one pathway not exercised: The path from the light blue node to the orange node. The point is that this diagram illustrates <em>high</em> code coverage, not complete code coverage. The following argument applies to that general situation. </p> <p> What happened with the above test is that coverage <em>decayed</em>. </p> <p> <img src="/content/binary/some-test-paths-through-complex-unit.png" alt="Diagram that shows several unit tests exercising one fewer paths through a unit that before."> </p> <p> In this figure, the green pathway is no longer exercised. </p> <p> Not only did coverage decrease: Unless you're monitoring code coverage, you probably didn't notice. The code didn't change. Time just passed. </p> <h3 id="c8a7facb117247baaddceca8ae45ffc6"> Threat to refactoring <a href="#c8a7facb117247baaddceca8ae45ffc6" title="permalink">#</a> </h3> <p> Why is this a problem? After all, code coverage isn't a goal; it's just a measure. </p> <p> As <a href="https://martinfowler.com">Martin Fowler</a> writes: </p> <blockquote> <p> "to refactor, the essential precondition is [...] solid tests" </p> <footer><cite>Martin Fowler, <a href="/ref/refactoring">Refactoring</a></cite></footer> </blockquote> <p> A good test suite verifies that the behaviour of your software doesn't change as you reorganise the code. The underlying assumption is that the test suite exercises important use cases and protects against regressions. </p> <p> The above test is an example of a test case that silently disappears. If you think that your tests cover all important use cases, you may feel confident refactoring. After all, if all tests pass, you didn't break any existing behaviour. </p> <p> Unbeknownst to you, however, the test suite may become less trustworthy. As time passes, test cases may disappear, as exemplified by the above test. While the test suite may be passing, a refactoring could introduce a regression - of behaviour you believed to be already covered. </p> <h3 id="ad442fa0b7dd4c7a9d46a71771d75184"> Under the radar <a href="#ad442fa0b7dd4c7a9d46a71771d75184" title="permalink">#</a> </h3> <p> Why didn't I catch this earlier? After all, <a href="/2021/01/11/waiting-to-happen">I'd already identified the problem</a> in the code base. Once I realised the problem, I took steps to remedy it. I loaded the code base on a spare computer and changed the machine's year to a future year (<a href="https://en.wikipedia.org/wiki/Year_2038_problem">2038</a>, if I recall correctly). Then I ran the tests to see which ones failed. </p> <p> I examined each failing test to verify that it actually failed because of the time and date. Then I corrected the test to make it relative to the system clock. </p> <p> That took care of all the tests that would eventually break. On the other hand, it didn't unearth any of the tests that over time silently would become false negatives. </p> <h3 id="c5bcb89e54714544b48c5cfbd7974e47"> Make it relative <a href="#c5bcb89e54714544b48c5cfbd7974e47" title="permalink">#</a> </h3> <p> Fixing the above test was easy: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">ChangeDateToSoldOutDate</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r1</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Some.Reservation.WithDate(DateTime.Now.AddDays(8).At(20,&nbsp;15)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r2</span>&nbsp;=&nbsp;r1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithId(Guid.NewGuid()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDayAfter() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.WithQuantity(10); &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;db.Grandfather.Add(r1); &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather.Add(r2); &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;r1.WithDate(r2.At).ToDto(); &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;sut.Put(r1.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>),&nbsp;dto); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">oRes</span>&nbsp;=&nbsp;Assert.IsAssignableFrom&lt;ObjectResult&gt;(actual); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StatusCodes.Status500InternalServerError, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oRes.StatusCode); }</pre> </p> <p> The only change is to the creation of <code>r1</code> and <code>r2</code>. The test now explicitly sets the <code>r1</code> date eight days in the future. It also derives <code>r2</code> from <code>r1</code>, which makes the relationship between the two values more explicit. This in itself is a small improvement, I think. </p> <h3 id="7caaa6f5a1874d23a4712af241a2b87d"> Deterministic behaviour <a href="#7caaa6f5a1874d23a4712af241a2b87d" title="permalink">#</a> </h3> <p> More than one person has told me that I obsess over details to a degree that can't be expected of most developers. If that's true, problems like this are likely to go unnoticed. After all, I discovered the problem because I was carefully reviewing each test more than a year after I originally wrote it. While I had a reason to do that, we can't expect developers to do that. </p> <p> Are we doomed to suffer this kind of error, then? I don't have a <a href="/2019/07/01/yes-silver-bullet">silver bullet</a> for you, but I don't think that all is lost. A little discipline may help. As I write in <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, pair programming or code reviews can help raise awareness of issues. </p> <p> On the tactical level, you might want to consider a policy that discourages absolute dates and times in unit tests. </p> <p> On the strategic level, you may want to adopt the <a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">Functional Core, Imperative Shell</a> architecture. After all, <a href="/2015/05/07/functional-design-is-intrinsically-testable">pure functions are intrinsically testable</a>. </p> <p> As I wrote in the beginning of this article, most people tend to focus on how to avoid side effects when discussing functional programming. A <a href="https://en.wikipedia.org/wiki/Pure_function">pure function</a>, however, must be <em>both</em> side-effect-free and deterministic. </p> <p> This means that instead of learning many specific rules (such as not using absolute time in unit tests), you may focus on one general rule: Write and test pure functions. </p> <p> To be honest, though, this rule doesn't solve all problems. Even in a functional-core-imperative-shell architecture, the imperative shell isn't pure. The above integration test is, unfortunately, a test of the imperative shell. It's already using the <code>SystemClock</code>, and that's no oversight on my part. While I do favour the <a href="https://martinfowler.com/bliki/TestPyramid.html">test pyramid</a>, I also write integration tests - just as the test pyramid encourages me to do. I find it valuable that integration tests integrate as many components as possible. The more real components an integration test uses, the better the chance that it uncovers problems. </p> <p> With integration tests, then, diligence is required to keep tests deterministic. In that context you can't rely on a universal rule like <em>just write pure functions</em>, because <a href="/2022/05/02/at-the-boundaries-applications-arent-functional">at the boundaries, programs aren't functional</a>. Instead, some diligence and discipline is required. At least, I don't see other alternatives, but perhaps you do? </p> <h3 id="d92d984d1c064aa1ac11d5bc01854e57"> Conclusion <a href="#d92d984d1c064aa1ac11d5bc01854e57" title="permalink">#</a> </h3> <p> If you use absolute dates in unit tests, what was once a future date may some day become a past date. This can change which pathways of the System Under Test an automated test exercises. </p> <p> Is this important? It's probably not the most pressing problem you may run into. Even if test coverage silently decays, it may not be a problem if you never refactor the code in question. It's only if, during a refactoring, you introduce a defect that goes unnoticed that this may become a problem. It doesn't seem like the most likely of errors, but on the other hand, these kinds of unexpected problems have a tendency to occur at the most inopportune moments. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="c0b2e0bd555b5d5c5555c60bf11bff69"> <div class="comment-author"><a href="https://github.com/ladeak">Laszlo</a></div> <div class="comment-content"> <p> Why have you decided to make the date of the reservation relative to the SystemClock, and not the other way around? Would it be more deterministic to use a faked system clock instead? </p> </div> <div class="comment-date">2022-05-30 17:12 UTC</div> </div> <div class="comment" id="552d192249594844937724b2b2f86efe"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Laszlo, thank you for asking. I wrote <a href="/2022/06/27/test-double-clocks">a new article</a> to answer your question. </p> </div> <div class="comment-date">2022-06-27 5: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>. 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> <a href="/2022/05/30/the-lazy-monad">The Lazy 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>. 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.0&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;d); &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><a href="/2022/05/30/the-lazy-monad">The Lazy monad</a></li> <li><a href="/2022/06/06/asynchronous-monads">Asynchronous monads</a></li> <li><a href="/2022/06/20/the-state-monad">The State monad</a></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); &n