Is it possible to put together a computation expression builder that can sequence two or more expressions without putting do! in front of each one?
If I've read the relevant section of the manual correctly, this should be possible through the builder's Combine method. However, my Combine method doesn't appear to be used; instead, I get a compiler warning suggesting that I use ignore to discard the result.
For instance, given an F# State monad, I'd like to be able to do this:
let hello who = State (fun lines -> lines @ [sprintf "hello %s" who])
let m = state {
hello "world"
hello "F#"
}
let l = Execute m []
// l should now contain ["hello world"; "hello F#"]
In addition to what Dario wrote, you cannot redefine the usual sequencing to behave as monadic do! (even if you decided not to support non-monadic operations in your computations). The problem is that usual sequencing isn't handled in any special way by the translator, so there is no interception point that you could use. Your example will be translated like this:
let m = state.Delay(fun () ->
hello "world"
hello "F#"
state.Zero())
The call to hello is not wrapped into any member call that could be redefined.
In an earlier version of F# sequencing used to be translated to calls to Let member like this:
let m = state.Delay(fun () ->
state.Let(hello "world", fun _ ->
state.Let(hello "F#", fun _ ->
state.Zero())))
So it was possible to do what you wanted, but it cannot be done in the current version (I believe one reason was that this adds too much wrapping which hurts the performance).
No, because that's what regular do is for. If you want monadic do, i.e. do!, you have to be explicit. Example:
let m = state {
printfn "World"
hello "World"
return 42
}
printfn expression is of type unit, and there is a do printfn implicit.hello case? We'd need monadic binding!Now how would the compiler know what to choose, do or do!? Maybe by types (Scala does this), but right now, it doesn't. So it just assumes a regular do anywhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With