2012-02-03 5 views
11

トランスパッケージを見て、IdentityTというモナド変圧器が見つかりました。IdentityT変圧器の目的は何ですか?

私はアイデンティティモナドを使用する方法を理解する(例えばStateStateT Identityのためだけのエイリアスです)、どのようにモナド変圧器は、一般的に動作しますが、私はそれがIdentityTにどのように関連するか見当がつかない。

MTLにはないので、完全性のためにそこに追加されていると思いますが、実用的ではありません。あれは正しいですか?

答えて

6

まあリンクドキュメントが

これはモナド変換によってパラメータの機能のために有用であると言っています。

私はこれが実際にどのような状況であるかはわかりませんが、理論的には、のためにfoo :: (MonadTrans t, Monad m) => t m a -> bのような関数がある場合は、t = IdentityTを使って本質的にm a -> bに「ダムダウン」することができます。

しかし、IdentityTは、MonadTransとなり、Identityは、Monadとなります。 Identityは「パススルー」のモナドであるため、「パススルー」トランスです。ちょうどソースをチェックしてください。むしろ単純です。 IdentityT SomeMonad aは、SomeMonad aと同じように動作する必要があります。唯一の違いは、新しいタイプの追加です(コンパイル時にはもちろん削除されます)

2

提案使用量はIdentityTのおそらく起源(ここにあります: http://www.haskell.org/pipermail/libraries/2007-June/007563.html

主な用途は、ソースコードレベルでの柔軟性を可能にするためであると考えられる、例えば、誰かが自分のUserTをxmonadと置換するソースを編集することができますあまりにも多くのコードを編集することなく。

私はそれがライブラリーのためにどのように機能するかを見てみました。スタックの真ん中にモナドを挿入するためのプレースホルダを提供するために使用できます。それは私の考案した例です:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

module Main where 

import Control.Monad.State 
import Control.Monad.List 
import Control.Monad.Reader 

type X m a = StateT Int (m IO) a 

something :: (Monad (m IO), MonadIO (m IO)) => (m IO) Int -> X m Int 
something a = do 
     x <- lift a 
     put (x + 1) 

     liftIO $ print x 
     return x 



listSomething = something $ ListT (mapM return [1,2,3,4]) 
plainSomething = return 5 :: IdentityT IO Int 

main = do 
    x <- runListT (execStateT listSomething 3) 
    print x 

    y <- runIdentityT (execStateT plainSomething 3) 
    print y 

runIdentity $ mapM (return . (+1)) [1..100] 
関連する問題