[plt-scheme] Re: computational expressions

From: Jake Swenson (cipherzero at gmail.com)
Date: Wed Mar 17 01:46:21 EDT 2010

You're correct, you cannot simply thread a function into a computational
As you mentioned, the expansion only happens with the known syntatic forms.
One obvious one is return which gets desugared to a call to the Return method
on the builder object.

However, you could do:

let myReturn x = return x;;
parse { let! t = token
        return! myReturn t }

(note: return! gets transformed into a call to ReturnFrom on the builder

but this is quite ugly IMO.

More interesting is that you could use inheritance to extend the expression
For example:

let bind m f = f (m ())
let return' v = fun () -> v

type ParserBuilder() =
    member this.Bind(m,f) = bind m f
    abstract member Return : int -> (unit -> int)
    default this.Return(x) = return' x

let parse = ParserBuilder()

let fx =
    parse { let! t = return' 4
            return t}

printfn "%i" (fx())

let myReturn x = return' (4*x)

type MyParserBuilder() =
    inherit ParserBuilder()
    override this.Return(x) = myReturn x

let myParse = MyParserBuilder()

let myfx =
    myParse { let! t = return' 4
              return t}

printfn "%i" (myfx())

which gets you almost the same abstraction, right?


 On Tue, Mar 16, 2010 at 4:03 PM, John Clements
<clements at brinckerhoff.org>wrote:

> Which is better? Haskell or F#?
> Wait, wait, no, that's not what I meant at all.
> I was reading up on F#'s computational expressions last night, and I'm
> impressed by their flexibility.  I do see one teeny tiny thing that's
> missing, though.
> In particular, it looks like computation expressions (e.g.
> parse { let! e = token
>       return e}
> Are a lot like Haskell's monads. In fact, in one way they're nicer; rather
> than just bind and return, you get a whole bunch of syntactic forms that you
> can redefine.
> But! If I understand correctly, these overridings happen only within the
> syntactic boundaries of the curly braces, right?  So you couldn't abstract
> over those pieces in quite the same way.
> E.G:
> let myReturn x = return x;;
> parse { let! t = token
>        myReturn t}
> ... wouldn't work, right?
> Whereas Haskell gets it right:
> myReturn = return
> p = do t <- token
>       myReturn t
> I haven't tried actually running any of this, mind you. Of course, Scheme
> can't do this, either; it's a consequence of Haskell's truly insane type
> system.
> John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100316/66060ccc/attachment.html>

Posted on the users mailing list.