モナドを使ったプログラミング
持ち上げの一般化(15.2)
liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r Prelude Control.Monad> :t liftM liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r Prelude Control.Monad> :t ap ap :: (Monad m) => m (a -> b) -> m a -> m b
liftM(N)はliftMとapを使って一般化できる。
Readerモナドを大体理解した(15.6)。
newtype Reader e a = R { runReader :: e -> a } instance Monad (Reader e) where return a = R $ \_ -> a m >>= k = R $ \r -> runReader (k (runReader m r)) r ask :: Reader e e ask = R id
askで得た環境を引き回す。
*Main Data.Char> runReader (ask >>= \x -> return (x*3)) 2 6
askで常に同じ環境が返ってくる、読み取り専用のStateみたいなもんか。