[Chapter 17 done Bryan O'Sullivan **20080420212503] { hunk ./en/ch17-monad-trans.xml 388 + We use the name lift based on its + similarity to fmap and + liftM: in each case, we hoist something + from a lower level of the type system to the level we're + currently working in. + + + + fmap elevates a pure function to + the level of functors; + + + liftM takes a pure function to the + level of monads; + + + and lift raises a monadic action + from one level beneath in the transformer stack to the + current one. + + + hunk ./en/ch17-monad-trans.xml 685 - look at the strengths and weaknesses of programming with monads + look at the weaknesses and strengths of programming with monads hunk ./en/ch17-monad-trans.xml 688 - Probably the biggest irritation of working with monads is - that a monad's type constructor often prevents us from using - pure code. Many useful pure functions need monadic - counterparts. + + Interference with pure code + + Probably the biggest practical irritation of working with + monads is that a monad's type constructor often gets in our + way when we'd like to use pure code. Many useful pure + functions need monadic counterparts, simply to tack on a + placeholder parameter m for some monadic + type constructor. + + &monadProblems.ghci:filter; + + However, the coverage is incomplete: the standard + libraries don't always provide monadic versions of pure + functions. + + &monadProblems.ghci:zip; + + The reason for this lies in history. Eugenio Moggi + introduced the idea of using monads for programming in 1988, + around the time the Haskell 1.0 standard was being developed. + Many of the functions in today's Prelude date + back to Haskell 1.0, which was released in 1990. + + Not until 1996, and the release of Haskell 1.3, did the + standard acquire support for monads. By this time, the + language designers were already constrained by backwards + compatibility: they couldn't change the signatures of + functions in the Prelude, because it would have + broken existing code. + + Since then, the Haskell community has learned a lot about + creating suitable abstractions, so that we can write code that + is less affected by the pure/monadic divide. You can find + modern distillations of these ideas in the + Data.Traversable and Data.Foldable + modules. As appealing as those modules are, we do not cover + them in this book. This is in part for want of space, but also + because if you've still following our book at this point, you + won't have trouble figuring them out for yourself. + + In an ideal world, would we make a break from the past, + and switch over Prelude to use + Traversable and Foldtable types? + Probably not. Learning Haskell is already a stimulating + enough adventure for newcomers. The Foldable and + Traversable abstractions are easy to pick up when + we already understand functors and monads, but they would put + early learners on too pure a diet of abstraction. For + teaching the language, it's good that + map operates on lists, not on + functors. + + + + Overdetermined ordering + + One of the principle reasons that we use monads is that + they let us specify an ordering for effects. Look again at a + small snippet of code we wrote earlier. + + &MTComposition.hs:problem.noid; + + Because we are executing in a monad, we are guaranteed + that the effect of the tell will occur + before the effect of fail. The problem + is that we get this guarantee of ordering even when we don't + necessarily want it: the compiler is not free to rearrange + monadic code, even if doing so would make it more + efficient. + + + + Runtime overhead + + Finally, when we use, monads and monad transformers, we + pay an efficiency tax. For instance, the State + monad carries its state around in a closure. Closures might + be cheap in a Haskell implementation, but they're not + free. + + A monad transformer adds its own overhead to that of + whatever is underneath. Our MaybeT transformer + has to wrap and unwrap Maybe values every time we + use &bind;. A stack of MaybeT on top of + StateT over ReaderT thus has a lot + of book-keeping to do for each &bind;. + + A sufficiently smart compiler might make some or all of + these costs vanish, but that degree of sophistication is not + yet widely available. + + + + Unwieldy interfaces hunk ./en/ch17-monad-trans.xml 784 - &monadProblems.ghci:filter; + If we use the mtl library as a black box, all + of its components mesh quite nicely. However, once we start + developing our own monads and monad transformers, and using + them with those provided by mtl, some + deficiencies start to show. hunk ./en/ch17-monad-trans.xml 790 - However, the standard libraries don't always provide monadic - versions of pure functions. + For example, if we create a new monad transformer + FooTand want to follow the same pattern as + mtl, we'll have it implement a type class + MonadFoo. If we really want to integrate it + cleanly into the mtl, we'll have to provide + instances for each of the dozen or so mtl type + classes. hunk ./en/ch17-monad-trans.xml 798 - &monadProblems.ghci:zip; + On top of that, we'll have to declare instances of + MonadFoo for each of the dozen or so + mtl transformers. Most of those instances will + be almost identical, and quite dull to write. Worse, if we + want to keep integrating new monad transformers into the + mtl framework, the number of moving parts we must + deal with increases with the square of + the number of new transformers! hunk ./en/ch17-monad-trans.xml 807 + In fairness, this problem only matters to a tiny number of + people. Most users of mtl don't need to develop + new transformers at all, so they are not affected. + + This weakness of mtl's design lies with the + fact that it was the first library of monad transformers that + was developed. Given that its designers were plunging into + the unknown, they did a remarkable job of producing a powerful + library that is easy for most users to understand and work + with. + + A newer library of monads and transformers, + monadLib, corrects many of the design flaws in + mtl. If at some point you turn into a hard core + hacker of monad transformers, it is well worth looking + at. + + + + Pulling it all together + + Monads are not by any means the end of the road when it + comes to working with effects and types. What they are is the + most practical resting point we have reached so far. Language + researchers are always working on systems that try to provide + similar advantages, without the same compromises. + + Although we must make compromises when we use them, monads + and monad transformers still offer a degree of flexibility and + control that has no precedent in an imperative language. With + just a few declarations, we can rewire something as fundamental + as the semicolon to give it a new meaning. + }