lifting
モナドスタックが深くなると
list $ lift $ lift $ foo
のようにしないといけない
こう対応関係を見るとわかりやすい
fmap
liftM
モナドの関数
この表現、わかりにくくない?

普通の関数をモナド値に適用できる、とかのほうがわかり易くない?

理解するのはliftより簡単
lift
モナド変換子の関数
アクションを変換子層の一つ下のレベルから現在の層へ持ち上げ
Monad m => (a1 -> r) -> m a1 -> m r
MonadTrans型クラスの中で定義されている
lift :: (Monad m) => m a -> t m a
t
はモナド変換子
「持ち上げ」と訳される
モナドからモナド変換子を生成する
モナド変換子版のreturn
liftすることで内側のモナドアクションを使えるようになる
hsimport Control.Monad.State
a :: StateT String IO ()
a = do
v <- get -- Stateアクション
lift $ print v -- IOアクション
main = do
runStateT a "hello"
hsclass MonadTrans t where
lift :: Monad m => m a -> t m a
IOモナドはモナドスタックの常に最深部にいる
そこまで lift $ lift $ lift $ ..
と繰り返していくのが面倒なので、 liftIO
で一発でそこまでliftingできる
MonadIO型クラス内で定義されている
hsclass (Monad m) => MonadIO m where
liftIO :: IO a -> m a
instance MonadIO IO where
liftIO = id
lifting則
実際に「lifting則」という名前がついているのかは知らない


が適当に言っている
liftingにもモナド則のような法則がある
refhs-- 1
lift . return = return
-- 2
lift (m >>= f) = lift m >>= (lift . f)
参考