23
votes

When browsing Hackage, most of the monads have a Lazy and a Strict version. What is the difference exactly? Can you highlight it with some examples for the common monads (State, Reader, Writer)?

1

1 Answers

35
votes

I don't know of a separation into lazy and strict for the reader monad, the reason for the State(T) and Writer(T) separation doesn't apply there.

The difference between the lazy and strict Writer and State monads resp. their monad transformers is the implementation of the monadic bind (>>=), fmap etc. In the strict versions, the implementation pattern-matches on the pair ((result, state), resp. (result, message)), forcing its evaluation (not the evaluation of its components), while the lazy versions use an irrefutable pattern ~(a,w) there, which does not force the evaluation of the pair.

The lazy versions allow some applications that are not possible for the strict versions, e.g.

foo = do
    xs <- take 100 `fmap` sequence (repeat someAction)
    doSomethingWith xs

the sequence of an infinite list of actions can only start delivering its result if the (>>=) of the monad is sufficiently lazy.

On the other hand, using the lazy versions often leads to the build-up of large thunks in the (result, state) pairs, and thus to space and/or time leaks.

So both variants are offered, and you can choose which suits your needs better.