10

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?

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

3 Answers 3

12

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.

6
  • 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. Commented Jun 22, 2012 at 13:55
  • BTW--there is a monad type of concept in F#; it's called a computation expression. Commented 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. Commented 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. Commented 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". Commented Jun 7, 2016 at 22:44
10

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 -> None |> 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.

4

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.