Monad Transformer Workshop
April 9, 2017
Newsletter ↳
Azad Bolour believes that monad transformers are usually explained with insufficient motivation. He presents them in relation to ordinary function composition, using a novel perspective gained from participating in a monad transformer study group.
His talk has three parts:
- Motivation - why use transformers, how to derive them from first principles
- Implementation - getting into the specifics of MaybeT
- Usage - the way they play out in programs at large
This workshop includes a link to a repo of exercises. With this video and exercises you can get the full hands-on experience, and develop confidence using monad transformers for real-world Haskell.
Exercises: github.
Motivation
- This talk assumes you know about monads but not monad transformers
- Initially Azad had a problem getting enough motivation and background about what is going on with transformers
- Why learn them?
- If you’re going to be doing Haskell you’ll be using monads, but each one has only a single effect at a time
- Monad transformers combine and propagate the effects of different monads
- A lot of real-world haskell uses monad transformers, and we need to understand them in order to understand and troubleshoot those programs
- If you’re going to create monads yourself, you can often make them more easily using transformers
- When creating new monads you’ll want to create transformers to combine them with others
- Generally a search for monad transformers on google leads to complicated stuff, and even the source code is hard
- Example of using the Persistent library
- An analogy with function composition
- Let’s start with the notion of function composition. We’re familiar with
(.)… how about(>=>)? It’s the closest monadic analog to composition. - This operator uses the same monad everywhere:
(>=>) :: (a -> m b) -> (b -> m c) -> (a -> m c)but what about using different m’s? - We could call it
hcompose, or heterogeneous compose. Azad calls functionsa -> m b“monad producers” or “monad factories.” - Deriving what
hcomposeshould be for various combinations of monads. - A source of confusion: monads (like
Reader) are defined in the standard library in terms of transformers (like ReaderT). In its purist sense reader is just((->) r), notReaderT r Identity. The library uses a standard, but complex, infrastructure to define some of the monads.
- Let’s start with the notion of function composition. We’re familiar with
- Definition of Monads
- Moving toward heterogeneous composition, starting at Kleisli composition
- The crux is a heterogeneous
joinwhich flattens across two monads - Exposition in terms of fictitious “blenders”
- Moving from blenders to transformers
- lift vs return
- lift via heterogeneous bind
- MonadTrans has laws too (Azad prefers the Kleisli form of exposition)
- Graphical representation of composition law
Implementation
- Reiteration of Azad’s shorthand notation
- Example of lifting a list with MaybeT
- Implementing MaybeT as a Functor (unbox - apply - box)
- Graphical representation of nested fmap
- (Not doing Applicative live)
- A transformation trick for monads that are functions
- Creating monads by applying transformers to the Identity monad
- transformer packages
Usage
- Stacking transformers
- Nesting order reverses in the core
- Example in this workshop comes from Monad Transformers Step by Step, a very instructive paper
- Makes an evaluator for a simple language and continuously adds effects
- Steps in building the evaluator transformer stack