これは私の最初のモナドトランスフォーマーとの知り合いです。モナド内部モナド変換器の結果
私はStateT MyMonad MyType型のdoブロックの中にいるとしましょう。同じ型の別の関数が状態を変更してMyMonad MyType型の値を返すようにしたいとします。それをどうすれば実現できますか?私は例をhere guessSessionでそれを表示すると思うが、私はそれを適用する方法を理解できないようです!
これは私の最初のモナドトランスフォーマーとの知り合いです。モナド内部モナド変換器の結果
私はStateT MyMonad MyType型のdoブロックの中にいるとしましょう。同じ型の別の関数が状態を変更してMyMonad MyType型の値を返すようにしたいとします。それをどうすれば実現できますか?私は例をhere guessSessionでそれを表示すると思うが、私はそれを適用する方法を理解できないようです!
あなたがモナド変換子に根本的なモナドを使用する場合は、lift
を使用することができますが、この場合には
lift :: (MonadTrans t, Monad m) => m a -> t m a
、t
はStateT MyState
あり、そしてm
はMyMonad
です。したがって、たとえば:
foo :: StateT MyState MyMonad MyType
foo = do
modify $ \s -> s+1
lift $ doSomethingInMyMonad 42
モナド変圧器を使用すると、内部からタイプMyMonad MyType
の値を返すだろうという意味で「上に積層」されていません。より多くのリテラルの変形です:彼らは変形されたモナドでアクションを実行する能力を持つ新しいものにモナドを回します。だからStateT s m
を普通のState s
モナドと考えることができますが、を使用してm
の行動をStateT s m
に実行することができます。
あなたがなどStateT
、ReaderT
、などの標準Monad Transformer Library(MTL)変圧器を使用している場合は、実際にlift
を使用する必要はありません。 modify
とask
のようなものは、ののモナドで動作し、スタックのどこかに正しいトランスフォーマがあります。 (スタックはStateT s (ReaderT r IO)
のように、変換されたモナドのほんの塔です。)
また、あなたが底にIO
を持つ大規模なスタックを持っている場合は、任意の数の層をIO
アクションを持ち上げる便利な機能があります:
liftIO :: (MonadIO m) => IO a -> m a
のでIO
でliftIO (putStrLn "Hello, world!")
作品、StateT Int IO
、その上ContT r (WriterT [String] IO)
、と。
(追加のノート、foo
としてここでは実際には関数ではありません。より正確な用語はアクションまたは計算です。)あなたがhoogleについて知らない場合には
私は理解していると思います。ただ完全にはっきりするために。 StateTを追加する前にdoSomethingInMyMonad 42を実行したとします。今私は< - リフト$ doSomethingInMyMonad 42を行う。正しい? – aelguindy
@aelguindy:うん! 'MyMonad'だけを使用するコードセクションがある場合は、doブロック全体を持ち上げることもできます:' lift $ do ... '。 – ehird
ありがとう!これが正しい場所であるかどうかはわかりませんが、2つの引数lift2を使用して持ち上げることはできますか? *ばかげた質問!*答えを見つけた – aelguindy
ます。http:// www.haskell.org/hoogle – jberryman