One of the annoyances of using monads in OCaml is that the syntax is awkward. You can see why if you look at a simple example. Assume that you’re using the usual option monad. If we define >>= to be the bind operator, you might end up with a piece of code that looks like this:

let f x_opt y_opt z_opt =
  x_opt >>= (fun x ->
        y_opt >>= (fun y ->
              z_opt >>= (fun z ->
                    return (x + y + z))))

This is awful for two reasons: the indentation is absurdly deep, and secondly, and there are too many closing parens at the end. One solution to this is

pa_monad, a camlp4 syntax extension that lets you write the same piece of code like this:

let f x_opt y_opt z_opt =
  perform
  x <-- x_opt;
  y <-- y_opt;
  z <-- z_opt;
  return (x + y + z)

This is much less painful to look at, but introducing new syntax has a cost, and it’s worth seeing if we can make things more livable without resorting to a syntax extension. We can make our original code less eye-gougingly awful by just changing the indentation:

let f x_opt y_opt z_opt =
  x_opt >>= (fun x ->
  y_opt >>= (fun y ->
  z_opt >>= (fun z ->
  return (x + y + z))))

That still leaves the parens. But as it happens, the parens can simply be dropped! This was passed on to me by Adam Chlipala, who got it in turn from Xavier Leroy at POPL this year. Our code can thus be written as follows:

let f x_opt y_opt z_opt =
  x_opt >>= fun x ->
  y_opt >>= fun y ->
  z_opt >>= fun z ->
  return (x + y + z)

This seems clean enough to actually use in practice. Now all I need is to coerce tuareg into indenting my code this way, and I’ll be happy…