{"id":2184,"date":"2022-10-10T20:56:10","date_gmt":"2022-10-10T20:56:10","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=2184"},"modified":"2022-10-11T08:27:48","modified_gmt":"2022-10-11T08:27:48","slug":"computational-expressions-the-standard-methods","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/computational-expressions-the-standard-methods\/","title":{"rendered":"Computational Expressions, the &#8220;standard&#8221; methods"},"content":{"rendered":"<p><em>Note: This post was written a while back but sat in draft. I&#8217;ve published this now, but I&#8217;m not sure it&#8217;s relevant to the latest versions etc. so please bear this in mind.<\/em><\/p>\n<p>So in a previous post I looked at my first attempt at creating a computational expression in F#. By anyone&#8217;s level this was basic. So I figured it was time to look at all the available &#8220;standard&#8221; methods available for a computational expression. By &#8220;standard&#8221; I means those which are implciitly recognized by F# as opposed to creating custom methods.<\/p>\n<p>See <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233182.aspx\" title=\"Computation Expressions (F#)\" target=\"_blank\" rel=\"noopener\">Computation Expressions (F#)<\/a> for more info.<\/p>\n<p>There are plenty of posts on this subject from Microsoft or F# for fun or profit, so why am I writing yet another post &#8211; basically just to give my perspective and to help me remember this stuff.<\/p>\n<p>Let&#8217;s start with the basics, we have a type SampleBuilder defined as<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype SampleBuilder() =\r\n   \/\/ our code will be filled is as required \r\n   \/\/ but an example might have just the following\r\n   member this.Bind(m, f) = f m\r\n<\/pre>\n<p>We shall use the builder thus<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet builder = SampleBuilder()\r\n\r\nbuilder {\r\n   \/\/ expressions, such as \r\n   let x = 100\r\n}\r\n<\/pre>\n<p>and now to the various builder methods&#8230;<\/p>\n<p><strong>Bind<\/strong><\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet! x = 100\r\n\r\n\/\/ translates to\r\n\r\nbuilder.Bind(100, (fun x -&gt; expression))\r\n<\/pre>\n<p>So as can be seen, in essence the order of the arguments is reversed. So if we were to simply duplicate the way <em>let<\/em> binding works but in a computational expression we&#8217;d write something like<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Bind(m, f) = \r\n   f m\r\n<\/pre>\n<p><strong>Return and ReturnFrom<\/strong><\/p>\n<p>At the time of writing this, I&#8217;m a little confused as to the difference between Return and ReturnFrom. <a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-wrapper-types\/\" title=\"Computation expressions and wrapper types\" target=\"_blank\" rel=\"noopener\">Computation expressions and wrapper types<\/a> states that the Return returns a wrapped type whilst ReturnFrom returns an unwrapped type. However it is seems it&#8217;s possible to pretty much return whatever I like as shown below<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Return(x) = x\r\n\r\nmember this.ReturnFrom(x) = x\r\n<\/pre>\n<p>Return is called when we have a return in the computation expression, i.e.<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {\r\n   return 100\r\n} |&gt; printfn &quot;%A&quot;\r\n<\/pre>\n<p>and ReturnFrom is used when return! exists, i.e.<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {\r\n   return! 100\r\n} |&gt; printfn &quot;%A&quot;\r\n<\/pre>\n<p>One slightly odd thing if you&#8217;re used to C# or the likes is that we can have multiple return and\/or return! in a computational expression as per<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {\r\n   return 100\r\n   return! 100\r\n} |&gt; printfn &quot;%A&quot;\r\n<\/pre>\n<p>As per multiple yield statements, we need a Combine method implemented in our builder to combine the return values. A return does not mean the rest of the computational expression is not executed, it means that the return values are combined to produce a value at the end of the workflow. So for example<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {\r\n   printfn &quot;First&quot;\r\n   return 100\r\n   printfn &quot;Second&quot;\r\n   return 100\r\n} |&gt; printfn &quot;%A&quot;<\/pre>\n<p>Assuming our Return method and Combine are as simple as the following<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Return(x) = \r\n   printfn &quot;Return&quot;\r\n   x\r\n\r\nmember this.Combine(a, b) = a + b\r\n<\/pre>\n<p>Then our output will look like the following<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nFirst\r\nReturn\r\nSecond\r\nReturn\r\n200\r\n<\/pre>\n<p>In other words, the first printfn (actually the Delay builder method is called for each printfn) is called then the Return method, then the second printfn then the second Return, then the Combine is called. In this case Combine simply adds the return values together to produce the output of the workflow.<\/p>\n<p><strong>Combine<\/strong><\/p>\n<p>The combine method combines multiple values &#8211; so for example if you had something like the following<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbuilder {\r\n   yield 100\r\n   yield 200\r\n} |&gt; printfn &quot;%A&quot;\r\n<\/pre>\n<p>without a combine method you&#8217;ll get the following compiler error <em>This control construct may only be used if the computation expression builder defines a &#8216;Combine&#8217; method<\/em>. Simple enough to see the problem here. So we cannot yield more than once unless we implement a combine method. Here&#8217;s an example which implements the combine by creating a list and combining elements into a new list<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Combine(a, b) = a @ b\r\n<\/pre>\n<p>If we now compile this code we&#8217;ll get another error, &#8220;This control construct may only be used if the computation expression builder defines a &#8216;Delay&#8217; method&#8221;. So we need to implement a Delay method. See the example listed for Delay below&#8230;<\/p>\n<p><strong>Delay<\/strong><\/p>\n<p>The Delay method allows the builder to delay the evaluation of a computational expression until it&#8217;s required. For example if we yield multiple times within a computational expression the idea is to combine the yields until we&#8217;re ready to invoke something. <\/p>\n<p>The example above creates a list of the yields and then in the Delay we might want to do something with those combined yields. In this example below we&#8217;ll simply use the following code<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Delay(f) = f()\r\n<\/pre>\n<p>which essentially just invokes the function passed to the delay.<\/p>\n<p><strong>Run<\/strong><\/p>\n<p>Whilst the Delay method is used to delay evaluation, the Run method is mean&#8217;t to use the delayed expression, i.e. it might be to run something or the likes. An example which simply turns the list created by the combine into an array instead<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Run(f) = Array.ofList f\r\n<\/pre>\n<p>this is obviously a rather simplistic example, had our builder been creating the data for a web service call, for example, possibly run would make the call for us.<\/p>\n<p><strong>For<\/strong><\/p>\n<p>I again must point anybody reading this section to the excellent post <a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-builder-part6\/\" title=\"Implementing a builder: The rest of the standard methods\" target=\"_blank\" rel=\"noopener\">Implementing a builder: The rest of the standard methods<\/a> where an implementation of the For method is describe, for simplicity I&#8217;ll recreate it here<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.For(sequence:seq&lt;_&gt;, body) =\r\n   this.Using(sequence.GetEnumerator(),fun enum -&gt; \r\n      this.While(enum.MoveNext, \r\n         this.Delay(fun () -&gt; body enum.Current)))\r\n<\/pre>\n<p>The Using, While and Delay methods are described elsewhere in this post.<\/p>\n<p>Here&#8217;s some sample code using the For method from our computational expression block<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {        \r\n   for i = 1 to 10 do\r\n      printfn &quot;%d&quot; i\r\n} \r\n<\/pre>\n<p><strong>TryFinally<\/strong><\/p>\n<p>An implementation of the TryFinally method is fairly straightforward<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.TryFinally(body, compensation) =\r\n   try this.ReturnFrom(body())\r\n   finally compensation() \r\n<\/pre>\n<p>and in usage within a computational expression block, we have<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {        \r\n   try\r\n      let x = 1 \/ 0\r\n      printfn &quot;should not make it to here&quot;\r\n   finally\r\n      printfn &quot;exception&quot;\r\n} \r\n<\/pre>\n<p>In the above code, when we step into the try block we will actually enter the TryFinally method and obviously this then takes over executing the body of the code and then executing the finally block.<\/p>\n<p><strong>TryWith<\/strong><\/p>\n<p>Very much like the TryFinally block, we have the following implementation<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.TryWith(body, handler) =\r\n   try this.ReturnFrom(body())\r\n   with e -&gt; handler e\r\n<\/pre>\n<p>and an example of the computational expression block might be<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {        \r\n   try\r\n      let x = 1 \/ 0\r\n      printfn &quot;should not make it to here&quot;\r\n   with\r\n   | :? DivideByZeroException -&gt; printfn &quot;divide by zero&quot;\r\n} <\/pre>\n<p><strong>Using<\/strong><\/p>\n<p>As the name suggests, this is used for IDisposable types. Here&#8217;s a sample of it&#8217;s implementation<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember thisTryFinally(body, compensation) =\r\n   try __.ReturnFrom(body())\r\n   finally compensation() \r\n\r\nmember this.Using(disposable:#System.IDisposable, body) =\r\n   let body' = fun () -&gt; body disposable\r\n   this.TryFinally(body', fun () -&gt; \r\n      match disposable with \r\n      | null -&gt; () \r\n      | disp -&gt; disp.Dispose())\r\n<\/pre>\n<p>The Using method relates to the <em>use!<\/em> keyword and hence we might have code such as<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {        \r\n   use! x = new MemoryStream()\r\n   printfn &quot;do something with the memory stream&quot;\r\n} \r\n<\/pre>\n<p>So at the point <em>use!<\/em> is invoked our Using method takes over. We i<\/p>\n<p><strong>While<\/strong><\/p>\n<p>The example of a while loop in a computational expression was lifted from <a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-builder-part6\/\" title=\"Implementing a builder: The rest of the standard methods\" target=\"_blank\" rel=\"noopener\">&#8220;Implementing a builder: The rest of the standard methods&#8221;<\/a> and I highly recommend anyone visiting this post goes and reads the computational expression series on F# for fun and profit.<\/p>\n<p>So our example code is as follows<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet mutable i = 0\r\nlet test() = i &lt; 5\r\nlet inc() = i &lt;- i + 1\r\n\r\nlet builder = SampleBuilder()\r\n\r\nbuilder {        \r\n   while test() do\r\n      printfn &quot;%i&quot; i\r\n      inc()         \r\n} |&gt; ignore\r\n<\/pre>\n<p>It&#8217;s important to note that the three let statements at the top of the source must be global or you&#8217;ll get an error along the lines of &#8220;The mutable variable &#8216;i&#8217; is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via &#8216;ref&#8217; and &#8216;!&#8217;.&#8221;<\/p>\n<p>So our builder code should look something like the following<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Bind(m, f) = f m\r\n\r\nmember this.Return(x) = x\r\n\r\nmember this.Zero() = this.Return ()\r\n\r\nmember this.Delay(f) = f\r\n\r\nmember this.Run(f) = f()\r\n\r\nmember this.While(guard, body) =\r\n   if not (guard()) \r\n   then \r\n      this.Zero() \r\n   else\r\n      this.Bind( body(), fun () -&gt; \r\n         this.While(guard, body))  \r\n<\/pre>\n<p>So as can be seen, in the While method we are passed the guard and the body of the while loop and as expected we need to invoke these bits of code to evaluate them. When the guard completes we invoke the Zero method which in this case simply called the Return method. If the loop has not completed we simply keep looping.<\/p>\n<p><strong>Yield and YieldFrom<\/strong><\/p>\n<p>We can use yield or yield! from a computational expression, but to do so we need to implement the Yield and YieldFrom methods (respectively) on the builder, otherwise we&#8217;ll be greeted with the &#8220;This control construct may only be used if the computation expression builder defines a &#8216;Yield&#8217; method&#8221;, here&#8217;s an example of the yield being used from a computational expression block<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {\r\n   yield 100\r\n} |&gt; printfn &quot;%A&quot;\r\n\r\n\/\/ or\r\n\r\nbuilder {\r\n   yield! 100\r\n} |&gt; printfn &quot;%A&quot;\r\n<\/pre>\n<p>An example of the Yield and YieldFrom methods in the builder might look like the following<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Yield(x) = Some x\r\n\r\nmember this.YieldFrom(x) = x\r\n<\/pre>\n<p><strong>Zero<\/strong><\/p>\n<p>You may have noticed, if you&#8217;ve written your own builder type that something like the following<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {\r\n}\r\n\r\n\/\/ or\r\n\r\nbuilder {\r\n} |&gt; ignore\r\n<\/pre>\n<p>doesn&#8217;t compile, this is because a computational expression <strong>must<\/strong> have something within the curly braces. So if instead we write the following<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nbuilder {\r\n   printfn &quot;Hello&quot;\r\n}\r\n<\/pre>\n<p>We&#8217;re get an altogether different error at compile time stating <em>This control construct may only be used if the computational expression builder defines a &#8216;Zero&#8217; method<\/em>. Basically a computational expression must return something, either explicitly or implicitly. In this case Zero is used for any implicit return, so we could resolve this error using <\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Zero() = ()\r\n<\/pre>\n<p>or ofcourse we might implicitly return the same thing we would with an explicit return such as<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmember this.Return(x) = x\r\n\r\nmember this.Zero() = this.Return ()\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Note: This post was written a while back but sat in draft. I&#8217;ve published this now, but I&#8217;m not sure it&#8217;s relevant to the latest versions etc. so please bear this in mind. So in a previous post I looked at my first attempt at creating a computational expression in F#. By anyone&#8217;s level this [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6],"tags":[],"class_list":["post-2184","post","type-post","status-publish","format-standard","hentry","category-f"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2184","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=2184"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2184\/revisions"}],"predecessor-version":[{"id":9570,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2184\/revisions\/9570"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=2184"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=2184"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=2184"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}