/emonad

Monads for erlang

Primary LanguageErlangApache License 2.0Apache-2.0

emonad

A lightweight monad library for erlang.

Generally speaking, monads aren’t the way to go in Erlang, however they may be useful in some very peculiar situations (e.g. parser combinators). To err on the side of sanity and to discourage Haskell hackers from abusing it, this library doesn’t try to achieve any kind of feature parity with Control.Monad. It means none of the usual suspects are found in this library:

For the same reason this library doesn’t support monad transformers.

emonad module defines an Erlang behavior with bind and return callbacks, as well as a parse transform that implements a poor man’s do notation:

-compile({parse_transform, emonad}).

...

[do/Module ||
  A <- foo(),
  B <- bar(),
  C = foobar(),
  quux()]

The above statement is transformed to:

Module:bind(foo(),
            fun(TMP1) ->
                case TMP21 of
                  A ->
                    Module:bind(bar(),
                                fun(TMP2) ->
                                    case TMP2 of
                                      B ->
                                        C = foobar(),
                                        quux();
                                      _ ->
                                        Module:nomatch(TMP2)
                                    end
                                end);
                  _ -> Module:nomatch(TMP1)
                end
            end)

Note a few things about the generated code:

  1. Variable bindings are preserved, so the following expression performs pattern matching on A, rather than re-assigns it:
    [do/Module ||
      A <- foo(),
      A <- bar(),
      ...]
        
  2. There is a third, non-standard callback nomatch/1: since this library has been developed with parser combinators in mind, we added it to simplify handling of unexpected tokens. This callback is optional, and defaults to raising badmatch exception, as one would expect.