人気ブログランキング | 話題のタグを見る

All About Monads 読解 20

Standard monad transformers

Haskell の標準ライブラリには、monad transformer をサポートするいくつかのクラスと、いくつかの標準モナドの transformer バージョンが収載されている。

The MonadTrans and MonadIO classes

MonadTrans クラスは、Control.Monad.Trans.Class で定義されている。MonadTrans クラスの関数は lift ひとつだけだ。lift 関数は、複合モナドの内側のモナド値 conputation を外側の複合モナドのモナド値に変換する。

class MonadTrans t where
    lift :: (Monad m) => m a -> t m a

IO モナドに特化された lift 関数をもつモナドは、MonadIO クラスのインスタンスだ。MonadIO クラスは Control.Monad.IO.Class に定義されている。MonadIO クラスのたったひとつの関数は liftIO だ。

class (Monad m) => MonadIO m where
    liftIO :: IO a -> m a

Transformer versions of standard monads

標準モナドに対しては、それに相当する transformer バージョンの複合モナドがある。しかし、それらが同じような方法で複合モナドに変換されているわけではない。たとえば、ContT 複合モナドは Cont モナドのコンテナの値の (a->r)->r 型の関数を、(a->m r)->m r 型の関数に変更しているが、StateT 複合モナドはそれとは異なっている。StateT 複合モナドは、State モナドのモナド値のコンテナの s->(a,s) 型の関数の代わりに、s->m (a,s) 型の関数を採用している。標準型のモナドを trannsformer バージョンの複合モナドに変換する一般的な法則はない。標準モナドのコンテキストでの意味を考えながら、transformer バージョンの複合モナドは作られている。次の表は、標準モナドと transformer バージョンの複合モナドとの対照表だ。

Standard MonadTransformer VersionOriginal TypeCombined Type
ErrorErrorTEither e am (Either e a)
StateStateTs -> (a,s)s -> m (a,s)
ReaderReaderTr -> ar -> m a
WriterWriterT(a,w)m (a,w)
ContContT(a -> r) -> r(a -> m r) -> m r


複合モナドを作るときは、組み合わせるモナドの順番が大切だ。StateT s (Error e) と ErrorT e (State s) では意味が違っている。前者は複合型の s -> Error e (a,s) を作り出す。これは、新しい状態を戻値として返すか、または、エラーを発生させる。後者は、複合型の s -> (Error e a,s) を作り出す。これは、モナド値 calculation は常に新しい状態を返すが、その値はエラーか、または、普通の値だ。

注:このセクションは総論的な記述なので細かい点は理解しづらいところがある。実例を何個か経験してからもう一度読み返すと分かりやすいのだろう。

前へ 目次 次へ
by tnomura9 | 2013-08-02 23:02 | Haskell | Comments(0)
<< All About Monad... Isomorphism, re... >>