I’ve never written a monad tutorial, but I’ve done the next best thing, which is writing a Haskell streaming library. It’s called jet-stream and it looks like this:
ghci> File "foo.txt" & J.jet @Line & J.limit 10 & J.sink stdout
The initial motivation was not within Haskell, it was working with Java Streams. The Java
Stream type has the interesting feature that
flatMap is also an implicit
bracket: if the
Stream created within the callback allocates some resource, the resource it’s freed once
flapMap exits. Furthermore, it plays well with methods like
limit: if we
limit the result of a
flatMap, the finalizer is not lost, and it’s called when we exhaust the result of the
limit. I wondered how something like that would work in Haskell.
Another motivation is that I wanted a very simple streaming type with only one type parameter: the type of yielded elements. Also, its
Monoid instances should be analogous to those of normal lists. This has required some compromises: the effects are always in
IO (no monad transformers in sight) and sometimes exceptions are required to notify of errors.
There aren’t a lot of grouping operations, either, and they aren’t as elegant as they are for example in streaming. That said, you can interface with the foldl library for performing grouping as a “terminal step”.