I was doing a presentation on F# and was discussing the Option type when someone in the audience asked me if the Option type is F#'s implementation of the maybe monad. I know that's not the case but I did want to ask how the two concepts are related. I mean it seems to me that an option type might be the result of the operation of a maybe monad but I'm not even sure of that.

Would someone elucidate the relationship between the maybe monad and the option type in those functional languages which support it?

  • 4
    Just curious, but how do you know that's not the case? They look very similar to me.
    – user39685
    Jun 22, 2012 at 13:44
  • That's why I'm asking. Jun 22, 2012 at 13:53

3 Answers 3


Reading the documentation on F#'s Option type, it looks like it does behave pretty much exactly like the Maybe type in Haskell, in that it can model either 'nothing' (None in F#, Nothing in Haskell), or a value of its argument type (Some in F#, Just in Haskell).

In Haskell, however, Maybe is also a monad, and the plumbing is such that it allows for calculations on Maybe values, early-returning Nothing if any of the variables in the calculation is Nothing. Used this way, Maybe is a simple error handler (or rather, error-ignoring device), and the fact that it is a monad allows moving the boilerplate out of the way. Look at this wikipedia article for a nice concise example. I don't think Option supports this kind of monadic usage (in fact, I'm wondering whether there is any explicit concept of a monad in F# at all). If you want this behavior in .NET, I guess you'd use Option.Value for all your arguments, and wrap the whole calculation in a try / catch on NullReferenceException.

So, while Option is similar to the Maybe type, it is not an equivalent to the Maybe monad.

  • Thanks for the lucid explanation. Frankly I always considered they weren't the same (one's a type the other's a monad) but I wasn't altogether clear on how one related to the other. Jun 22, 2012 at 13:55
  • BTW--there is a monad type of concept in F#; it's called a computation expression. Jun 22, 2012 at 13:56
  • @OnorioCatenacci: Ah, OK. I haven't had an awful lot of F# exposure, so excuse me. Anyway, in Haskell, monads are types, more specifically, types of the Monad typeclass. Maybe is a plain old data type, but it also happens to implement Monad to provide this 'special' behavior.
    – tdammers
    Jun 22, 2012 at 14:23
  • 2
    in short: I don't at all agree that they're not equivalent. language constructs like type classes or polymorphism doesn't change a types fundamental mathematical properties and structure.
    – sara
    Jun 7, 2016 at 21:15
  • 2
    F#'s Option's map and bind functions behave identically to Haskell's Maybe's fmap and bind functions. They are both monads and have equivalent monadic behavior. Haskell just has a Monad typeclass that lets you manipulate monads, while in F# they're more like an abstract "design pattern".
    – Jack
    Jun 7, 2016 at 22:44

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 = 
    option {
        let! a = Some 4
        let! b = None
        return a + b

which is a sugared equivalent of something like this:

let c =
    (Some 4) 
    |> 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.


They're equivalent, and they're both monads. The difference is being a monad means something in Haskell - there's an explicit Monad typeclass and "do notation" can be used to eliminate a lot of boilerplate when writing monadic code. In F#, builder notation and let! and do! can be used to get rid of similar boilerplate, but there is not an explicit notion of a type "being a monad". Haskell's type system includes typeclasses (of which the general Monad class is) and higher kinded types (of which an individual Monad is), which allow writing code that works for all monads. F#'s type system has neither of these features.

So yes, F#'s Option and Haskell's Maybe are identical and both monads. It's just that Haskell gives you a lot more machinery to work with monads than F# does.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.