generated at
lifting
モナド変換子を扱う時の話
モナドスタックが深くなると list $ lift $ lift $ foo のようにしないといけない
これはmtlで回避することができる

こう対応関係を見るとわかりやすい
fmap
ただの関数をFunctor型クラスのレベルに持ち上げ
liftM
モナドの関数
ただの関数をMonad型クラスのレベルに持ち上げ
この表現、わかりにくくない?mrsekut
普通の関数をモナド値に適用できる、とかのほうがわかり易くない?mrsekut
理解するのはliftより簡単
lift
モナド変換子の関数
アクションを変換子層の一つ下のレベルから現在の層へ持ち上げ




Monad m => (a1 -> r) -> m a1 -> m r




MonadTrans型クラスの中で定義されている
lift :: (Monad m) => m a -> t m a
t はモナド変換子
「持ち上げ」と訳される
モナドからモナド変換子を生成する
モナド変換子版のreturn
liftすることで内側のモナドアクションを使えるようになる
hs
import Control.Monad.State a :: StateT String IO () a = do v <- get -- Stateアクション lift $ print v -- IOアクション main = do runStateT a "hello"
hs
class MonadTrans t where lift :: Monad m => m a -> t m a


IOモナドはモナドスタックの常に最深部にいる
そこまで lift $ lift $ lift $ .. と繰り返していくのが面倒なので、 liftIO で一発でそこまでliftingできる
MonadIO型クラス内で定義されている
hs
class (Monad m) => MonadIO m where liftIO :: IO a -> m a instance MonadIO IO where liftIO = id




lifting則
実際に「lifting則」という名前がついているのかは知らないmrsekut
mrsekutが適当に言っている
liftingにもモナド則のような法則がある ref
hs
-- 1 lift . return = return -- 2 lift (m >>= f) = lift m >>= (lift . f)


参考