lifting
普通の関数を、文脈付きの世界に持ち上げること
関数をより一般的な(抽象的な)計算の文脈で使えるようにする」操作
イメージ
例えば、以下のような普通の関数を考える
code:haskell
(+1) :: Int -> Int
これは、Just 3のような文脈付きの値には使えない
以下のようにすれば使える
code:haskell
fmap (+1) (Just 3) -- Just 4
この fmap は、まさに「(+1) を Maybe の文脈に lift する」操作である
Functor / Applicative / Monad の各レベルでの “lift”
それぞれの型クラスで「持ち上げ」の概念がある
Functor
fmap :: (a -> b) -> f a -> f b
普通の関数を Functor(例:Maybe, [], IO)の中に持ち上げる
Applicative
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
2引数関数を Applicative に持ち上げる
Monad
liftM :: (a -> b) -> m a -> m b
Functor の fmap と同じ意味(歴史的に Monad 用に別名)
Monad Transformer
lift :: m a -> t m a
下位のモナドの計算を、上位のモナドスタックに持ち上げる
Monad m => (a1 -> r) -> m a1 -> m r
https://gyazo.com/dd6b98736d001ecb17ab9307b7d7ed51
IOモナドはモナドスタックの常に最深部にいる
そこまでlift $ lift $ lift $ ..と繰り返していくのが面倒なので、liftIOで一発でそこまでliftingできる
MonadIO型クラス内で定義されている
code:hs
class (Monad m) => MonadIO m where
liftIO :: IO a -> m a
instance MonadIO IO where
liftIO = id
https://gyazo.com/803d59e2f91668786d5a5352f427cb96
実際に「lifting則」という名前がついているのかは知らないmrsekut.icon
mrsekut.iconが適当に言っている
liftingにもモナド則のような法則がある ref code:hs
-- 1
lift . return = return
-- 2
lift (m >>= f) = lift m >>= (lift . f)
参考