18

私が機能を持っているとしましょう

f :: State [Int] Int

および関数:

g :: StateT [Int] IO Int

fで使用してg、それらの間の状態を渡したいです。のライブラリ関数はあり
StateT (return . runState f)ますか?または、一般的に、対応するモナドを持つモナド変換子が与えられた場合、そのためのライブラリ関数はありますか?

4

3 に答える 3

5

さらに一般的には、トランスフォーマースタックの内層に変換を適用しようとしています。2つの任意のモナドの場合、型アノテーションは次のようになります。

fmapMT :: (MonadTrans t, Monad m1, Monad m2) => (m1 a -> m2 a) -> t m1 a -> t m2 a

基本的に高レベルfmap。実際、最終的なパラメーターのマップと組み合わせることは、おそらくさらに理にかなっています。

fmapMT :: (MonadTrans t, Monad m1, Monad m2) => (m1 a -> m2 b) -> t m1 a -> t m2 b

明らかに、これがすべての場合に可能になるわけではありませんが、「ソース」モナドIdentityの方が簡単である可能性がありますが、それが機能する場所に別のタイプクラスを定義することを想像できます。典型的なモナド変換子ライブラリには、このようなものはないと思います。ただし、ハッキングを閲覧すると、Monatronパッケージ内で非常によく似たものが見つかります。

class MonadT t => FMonadT t where
    tmap' :: FunctorD m -> FunctorD n -> (a -> b) 
             -> (forall x. m x -> n x) -> t m a -> t n b

tmap :: (FMonadT t, Functor m, Functor n) => (forall b. m b -> n b) 
        -> t m a -> t n a
tmap = tmap' functor functor id

の署名でtmap'は、タイプは基本的に、インスタンスを直接使用するのではなく、FunctorDアドホックな実装です。fmapFunctor

また、2つのFunctorのような型コンストラクターFとGの場合、のような型の関数はFからGへの自然変換(forall a. F a -> G a)を記述します。パッケージのどこかに必要なトランスフォーマーマップの別の実装がある可能性がありますが、よくわかりません。モナド変換子の圏論的バージョンはどうなるので、それが何と呼ばれるのかわかりません。category-extras

インスタンス(いずれかが持つ必要があります)と自然変換tmapのみが必要であり、はによって提供されるモナドからの自然変換があるため、必要な関数は 、「基本的な」モナドがとにかく、に適用されるトランスフォーマーの同義語として定義されます。これは、トランスフォーマーライブラリの場合に一般的に当てはまります。FunctorMonadMonadIdentityreturnFMonadTtmap (return . runIdentity)Identity

特定の例に戻ると、Monatronには実際にFMonadTforのインスタンスがあることに注意してくださいStateT

于 2010-11-09T21:41:27.133 に答える
5

あなたが求めているのは、モナドからへのマッピング(モナド射として知られている)StateT mですStateT n。私はmmorphライブラリを使用します。これは、モナド射を操作するための非常に優れたツールのセットを提供します。

State -> StateT m探している変換を実行するために、にIdentity埋め込まれたモナドを一般化する射を定義することから始めます。State

generalize :: Monad m => Identity a -> m a
generalize = return . runIdentity

次に、この射を持ち上げて、の内側のモナドに作用させますStateT。つまり、あるモナドから別のモナドへのマッピングを与える関数(たとえば、generalize射)が必要であり、モナド変換子のベースモナドに作用する関数を与えt Identity a -> t m aます。これはのクラスのhoist関数に似ていることがわかります。mmorphMFunctor

hoist :: Monad m => (forall a. m a -> n a) -> t m b -> t n b

ピースをまとめて、

myAction :: State s Int
myAction = return 2

myAction' :: Monad m => StateT s m Int
myAction' = hoist generalize myAction
于 2013-08-19T22:10:20.510 に答える
4

このような関数は、すべてのモナド変換子に対して定義できるわけではありません。Cont rたとえば、モナドを持ち上げることはできません。これはContT r IO、IOモナド(a -> IO r)の継続を純粋な継続()に変換する必要があるためですa -> r

于 2010-11-09T21:33:59.620 に答える