Yes, they're equivalent in the sense that the
Option type together with
Option.bind and type constructor
Some constitute a monad.
While monads (as in the
Monad typeclass) are a central part of Haskells identity, from a conceptual point of view they're a language-agnostic construct. A design pattern if you like. If you have a type, and you have a bind and a return function with specific signatures that obey a particular set of laws - you have a monad - regardless of the language you use.
F# computation expressions only provide a programmable syntax sugar for monads, similar to the do notation in Haskell. While there's no
Option computation expression builder provided out of the box, you can easily define a bare-bones one like this:
type OptionBuilder () =
member this.Bind(m, f) = Option.bind f m
member this.Return(a) = Some a
let option = OptionBuilder ()
And use it like this:
let c =
let! a = Some 4
let! b = None
return a + b
which is a sugared equivalent of something like this:
let c =
|> Option.bind (fun a ->
|> Option.bind (fun b ->
Some (a + b)))
Note how the builder members mirror the
Monad typeclass, and how you can write monadic - even if convoluted - code without a builder.