{"id":2137,"date":"2014-07-20T11:05:02","date_gmt":"2014-07-20T11:05:02","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=2137"},"modified":"2014-07-20T11:05:02","modified_gmt":"2014-07-20T11:05:02","slug":"my-first-attempt-as-implementing-a-computational-expression-in-f","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/my-first-attempt-as-implementing-a-computational-expression-in-f\/","title":{"rendered":"My first attempt as implementing a Computational Expression in F#"},"content":{"rendered":"<p>So this is my first attempt at implementing a computational expression in F#. I&#8217;m not going to go into definitions or the likes as to what computational expressions are as there are far better posts out there on this subject than I could probably write, at this time. I&#8217;ll list some in a &#8220;further reading&#8221; section at the end of the post.<\/p>\n<p>What I&#8217;m going to present here is a builder which really just creates a list of names &#8211; nothing particularly clever &#8211; but it gives a basic idea on getting started with computational expressions (I hope).<\/p>\n<p>So first off we need to create a builder type, mine&#8217;s called CurveBuilder<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype Items = Items of string list\r\n\r\ntype CurveBuilder() =\r\n    member this.Yield (()) = Items &#x5B;]\r\n\r\n    &#x5B;&lt;CustomOperation (&quot;create&quot;, MaintainsVariableSpace = true)&gt;]\r\n    member this.Create (Items sources, name: string) = \r\n        Items &#x5B; yield! sources\r\n                yield name ]\r\n<\/pre>\n<p>As this is just a simple demo, the only thing I&#8217;m doing is creating a list of strings which you would be correct in thinking that I could do easier using a collection class, but I&#8217;m really just interested in seeing the builder and it&#8217;s interactions without too much clutter, so go with me on this one&#8230;<\/p>\n<p>Before we discuss the builder code, let&#8217;s take a look at how we&#8217;d use a builder in our application<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet builder = CurveBuilder()\r\n\r\nlet curves = \r\n   builder {\r\n      create &quot;risky_curve1.gbp&quot;\r\n      create &quot;risky_curve2.usd&quot;\r\n   }\r\n<\/pre>\n<p>In this code we first create an instance of a CurveBuilder, then when we use the builder to create a list of the curves. The Yield method is first called on the CurveBuilder, returning an empty Items value. Subsequent calls to the <em>create<\/em> method then call the <em>Create<\/em> method of the CurveBuilder and, as can be seen, create a new Items value containing the previous Items plus our new curve name.<\/p>\n<p><strong>Simple enough but surely there&#8217;s more to this than meets the eye<\/strong><\/p>\n<p>The example above is a minimal implementation, of course, of a builder. You&#8217;ll notice that we have an attribute on one method (the Create method) and not on the Yield method.<\/p>\n<p>So the attribute <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh289709.aspx\" title=\"Core.CustomOperationAttribute Class (F#)\" target=\"_blank\">CustomOperation<\/a> is used on a member of a builder to create new &#8220;query operators&#8221;. Basically it extends the builder functionality with new operators named whatever you want to name them.<\/p>\n<p>On the other hand the Yield method is a &#8220;standard&#8221; builder method. There are several other methods which F# knows about implicitly within a builder class, including Return, Zero, Bind, For, YieldFrom, ReturnFrom, Delay, Combine, Run and more, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233182.aspx\" title=\"Computation Expressions (F#)\" target=\"_blank\">see Computation Expressions (F#)<br \/>\n<\/a> for a full list of &#8220;built-in workflows&#8221;. With these we can obviously produce something more complex than the example presented in this post &#8211; which is in essence a glorified &#8220;list&#8221; builder with snazzy syntax.<\/p>\n<p><strong>Discriminated Union gotcha<\/strong><\/p>\n<p>One thing I got caught out with from the above code is that I wanted to simply list the curves I&#8217;d created but couldn&#8217;t figure out how to &#8220;deconstruct&#8221; the discriminated union<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype Items = Items of string list\r\n<\/pre>\n<p>to a simple string list &#8211; at this point I claim ignorance as I&#8217;m not using F# as much as I&#8217;d like so am still fairly inexperienced with it.<\/p>\n<p>My aim was to produce something like this<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nfor curve in curves do\r\n   printfn &quot;Curve: %s&quot; curve\r\n<\/pre>\n<p>but this failed with the error <em>The type &#8216;Items&#8217; is not a type whose values can be enumerated with this syntax, i.e. is not compatible with either seq<_>, IEnumerable<_> or IEnumerable and does not have a GetEnumerator method<\/em><\/p>\n<p>I need to in essence disconnect the Items from the string list, to achieve this I found the excellent post <a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/discriminated-unions\/\" title=\"Discriminated Unions\" target=\"_blank\">Discriminated Unions<\/a>.<\/p>\n<p>The solution is as follows<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet (Items items) = curves\r\n\r\nfor curve in items do\r\n    printfn &quot;Curve: %s&quot; curve\r\n<\/pre>\n<p>Note: the <em>let (Items items) = curves<\/em><\/p>\n<p><strong>Further Reading<\/strong><br \/>\n<a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-builder-part1\/\" title=\"Implementing a builder: Zero and Yield\" target=\"_blank\">Implementing a builder: Zero and Yield<\/a><br \/>\n<a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-builder-part2\/\" title=\"Implementing a builder: Combine\" target=\"_blank\">Implementing a builder: Combine<\/a><br \/>\n<a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-builder-part3\/\" title=\"Implementing a builder: Delay and Run\" target=\"_blank\">Implementing a builder: Delay and Run<\/a><br \/>\n<a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-builder-part4\/\" title=\"Implementing a builder: Overloading\" target=\"_blank\">Implementing a builder: Overloading<\/a><br \/>\n<a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-builder-part5\/\" title=\"Implementing a builder: Adding laziness\" target=\"_blank\">Implementing a builder: Adding laziness<\/a><br \/>\n<a href=\"http:\/\/fsharpforfunandprofit.com\/posts\/computation-expressions-builder-part6\/\" title=\"Implementing a builder: The rest of the standard methods\" target=\"_blank\">Implementing a builder: The rest of the standard methods<\/a><\/p>\n<p><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233182.aspx\" title=\"Computation Expressions (F#)\" target=\"_blank\">Computation Expressions (F#)<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>So this is my first attempt at implementing a computational expression in F#. I&#8217;m not going to go into definitions or the likes as to what computational expressions are as there are far better posts out there on this subject than I could probably write, at this time. I&#8217;ll list some in a &#8220;further reading&#8221; [&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-2137","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\/2137","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=2137"}],"version-history":[{"count":18,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2137\/revisions"}],"predecessor-version":[{"id":2179,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2137\/revisions\/2179"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=2137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=2137"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=2137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}