[ANN] Monads - the missing monad transformers library

Since Lwt and Async are commonly used and monadic, were you planning to provide a transformer to combine your monads with them? (Actually I believe they’re really more of an applicative functor, but they have a monadic interface for a subset of their functionality.)

The Lwt, Async, and other IO monads usually do not provide transformers and they act as an initial monad in the wrap. Since every monad in Monads provides a transformer, you can use it to wrap the IO monad, e.g.,

module Lwt_or_error = Monad.Result.Error.Make(Lwt)

Also, have you benchmarked your monad transformers’ performance? State monads in particular are notoriously slow.

Yes I did, though I didn’t have enough time to publish the results, but with flambda the results are shocking. Basically, in comparison with the legacy compiler the speed up was of factor 20 and more, giving the same overhead as normal fold function with a non-trivial type of state. Basically, if the state type is boxed, then a computation in a state monad is nearly as fast as a hand-written loop. If the state is unboxed or a float, then the hand-written loop usually wins.

The main drawback is the compilation time and the executable, I’ve used -O3 will multiple passes, and high cost of inlining. Also, I had a few issues with stuck compilations and running out of memory or with the stack overflow. So the released library, as of 1.0 will have this overhead. I will later add proper optimizations to the package, as soon as I will find a combination that is robust, relatively fast, and produces the efficient code.

4 Likes