You&#39;re correct, you cannot simply thread a function into a computational expression.<div>As you mentioned, the expansion only happens with the known syntatic forms.</div><div>One obvious one is <font face="&#39;courier new&#39;, monospace">return</font> which gets desugared to a call to the <font face="&#39;courier new&#39;, monospace">Return</font> method on the builder object.</div>



<div><br></div><div>However, you could do:</div><div><br></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">let myReturn x = return x;;</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">parse { let! t = token</font></div>

<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        return! myReturn t }</font></div><div><br></div><div>(note: <font class="Apple-style-span" face="&#39;courier new&#39;, monospace">return!</font> gets transformed into a call to <font class="Apple-style-span" face="&#39;courier new&#39;, monospace">ReturnFrom</font> on the builder object)</div>

<div><br></div><div>but this is quite ugly IMO.</div><div><br></div>

<div>More interesting is that you could use inheritance to extend the expression builder.</div><div>For example:</div><div><br></div><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">let bind m f = f (m ())</font></div>

<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">let return&#39; v = fun () -&gt; v</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">type ParserBuilder() = </font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    member this.Bind(m,f) = bind m f</font></div>

<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    abstract member Return : int -&gt; (unit -&gt; int)</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    default this.Return(x) = return&#39; x</font></div>

<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font>
</div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">let parse = ParserBuilder()</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div>

<font class="Apple-style-span" face="&#39;courier new&#39;, monospace">let fx = </font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    parse { let! t = return&#39; 4 </font></div><div>

<font class="Apple-style-span" face="&#39;courier new&#39;, monospace">            return t}</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">printfn &quot;%i&quot; (fx())</font></div>


<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">let myReturn x = return&#39; (4*x)</font></div><div>

<font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">type MyParserBuilder() =</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    inherit ParserBuilder()</font></div>

<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    override this.Return(x) = myReturn x</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div>

<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">let myParse = MyParserBuilder()</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">let myfx = </font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    myParse { let! t = return&#39; 4 </font></div>

<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">              return t}</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">printfn &quot;%i&quot; (myfx())</font></div>

</div><div><br></div><div>which gets you almost the same abstraction, right?</div><div><br></div><div>-- <br>Jake<br><br>
<div class="gmail_quote">
On Tue, Mar 16, 2010 at 4:03 PM, John Clements <span dir="ltr">&lt;<a href="mailto:clements@brinckerhoff.org" target="_blank">clements@brinckerhoff.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



Which is better? Haskell or F#?<br>
<br>
Wait, wait, no, that&#39;s not what I meant at all.<br>
<br>
I was reading up on F#&#39;s computational expressions last night, and I&#39;m impressed by their flexibility.  I do see one teeny tiny thing that&#39;s missing, though.<br>
<br>
In particular, it looks like computation expressions (e.g.<br>
<br>
parse { let! e = token<br>
       return e}<br>
<br>
Are a lot like Haskell&#39;s monads. In fact, in one way they&#39;re nicer; rather than just bind and return, you get a whole bunch of syntactic forms that you can redefine.<br>
<br>
But! If I understand correctly, these overridings happen only within the syntactic boundaries of the curly braces, right?  So you couldn&#39;t abstract over those pieces in quite the same way.<br>
<br>
E.G:<br>
<br>
let myReturn x = return x;;<br>
<br>
parse { let! t = token<br>
        myReturn t}<br>
<br>
... wouldn&#39;t work, right?<br>
<br>
Whereas Haskell gets it right:<br>
<br>
myReturn = return<br>
<br>
p = do t &lt;- token<br>
       myReturn t<br>
<br>
<br>
<br>
I haven&#39;t tried actually running any of this, mind you. Of course, Scheme can&#39;t do this, either; it&#39;s a consequence of Haskell&#39;s truly insane type system.<br>
<font color="#888888"><br>
<br>
John<br><font class="Apple-style-span" color="#000000"><font class="Apple-style-span" color="#888888"><br></font></font></font></blockquote></div>
</div>