HaskellのMonadとMonad Transformerについて:IdentityとIdentityT

Identity Monad

HaskellのIdentity Monadは、値をそのまま保持する非常にシンプルなMonadです。以下はIdentity Monadの定義とインスタンスです。


newtype Idnty a = Idnty { runIdnty :: a }

instance Functor Idnty where
    fmap f (Idnty x) = Idnty (f x)

instance Applicative Idnty where
    pure a = Idnty a
    (Idnty f) <*> (Idnty x) = Idnty (f x)

instance Monad Idnty where
    (Idnty m) >>= k = k m

Identity Monadの重要な点は以下の通りです。

  • newtype Idnty a = Idnty { runIdnty :: a } Identityは値をそのまま保持します。この型はa型の値をIdnty型でラップします。
  • instance Monad Idnty where IdentityはMonadの法律に準拠します。bind操作は内部の値を取り出してそのまま次の関数に渡します。

Identity MonadのMonad法律の証明:

  1. return a >>= f ≡ f a return aIdnty aです。bind操作はこの値を取り出してfに渡します。
  2. m >>= return ≡ m 内部の値を取り出してそのままreturnに入れると、元の値がそのまま保持されます。
  3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g) 内部の値が正しく伝搬され、Monadの結合性が保たれます。

IdentityT Monad Transformer

IdentityTはMonad Transformerです。他のMonadをラップし、その上でMonadの機能を提供します。


newtype IdntyT m a = IdntyT { runIdntyT :: m a }

instance (Monad m) => Monad (IdntyT m) where
    return a = IdntyT (return a)
    (IdntyT m) >>= k = IdntyT (m >>= (runIdntyT . k))

instance MonadTrans IdntyT where
    lift = IdntyT

instance (MonadIO m) => MonadIO (IdntyT m) where
    liftIO = IdntyT . liftIO

IdentityTの重要な点は以下の通りです。

  • newtype IdntyT m a = IdntyT { runIdntyT :: m a } IdentityTは内部のMonadmをラップします。値はm a型で保持されます。
  • instance (Monad m) => Monad (IdntyT m) where IdentityTは内部のMonadmの上にMonadの機能を提供します。

IdentityTのMonad法律の証明:

  1. return a >>= f ≡ f a returnは内部のMonadのreturnを使用します。
  2. m >>= return ≡ m 内部のMonadのreturnを使用すると、値がそのまま保持されます。
  3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g) 内部のMonadの結合性が保たれます。

IdentityTのMonad Transformerとしての性質

IdentityTはMonad Transformerの基本的な性質を持ちます。特に、lift関数の定義はMonad Transformerの法律を満たします。

  1. lift . return ≡ return liftは内部のMonadのreturnをそのまま使用します。
  2. lift (m >>= f) ≡ lift m >>= (lift . f) 内部のMonadのbind操作が正しく伝搬されます。

6月13日 17:14 投稿