リスト内包表記とリストモナドのdo表記の関係性がわからない場合にはReal World Haskell 14章のUnderstanding the list monadか、すごいHaskellの13章を読んでおくと良いです。
モナド内包表記
栄光のグラスゴーHaskellコンパイルシステム利用の手引き バージョン7.4.2 (7.3.11)
モナド内包表記はリスト内包表記をあらゆるモナドに一般化したものである。これには並列内包表記(7.3.9. 並行リスト内包表記)と変換内包表記(7.3.10. 一般化(SQL風)リスト内包表記)を含む。
MonadComprehensions拡張を有効にして呼び出す。分かりやすいMaybeモナドで
$ ghci -XMonadComprehensions GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Prelude> Prelude> [x+y | x <- Just 5, y<- Just 3] Just 8 Prelude> [x+y | x <- Just 5, y<- Nothing] Nothing
Maybe箱に入って出てきますね。MaybeはもちろんMonadPlusのインスタンスなのでガードが使える。
Prelude> [x+y | x <- Just 5, y<- Just 3, x < 3] Nothing
続いてEitherを。これはControl.Monad.Errorを使う。
Prelude> :m +Control.Monad.Error Prelude Control.Monad.Error> [ x+y | x <- Right 5, y <- Right 3] Right 8 Prelude Control.Monad.Error> [ x+y | x <- Left "not a number", y <- Right 3] Left "not a number"
Stateモナドだってできるぞ。
Prelude Control.Monad.State> runState [x | x <- get] 3 (3,3)
しかしこれは読みにくい。