[plt-scheme] Re: computational expressions
You're correct, you cannot simply thread a function into a computational
expression.
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
object)
but this is quite ugly IMO.
More interesting is that you could use inheritance to extend the expression
builder.
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?
--
Jake
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>