5

これは Monad Transformers との私の最初の知り合いなので、答えは明白かもしれません。

StateT MyMonad MyType 型の do ブロック内にいるとしましょう。同じ型の別の関数で状態を変更し、MyMonad MyType 型の値を返すようにしたいとします。どうすればそれを達成できますか?ここの例はguessSessionでそれを示していると思いますが、それを適用する方法を理解できないようです!

4

1 に答える 1

9

モナド変換子で基礎となるモナドを使用したい場合は、次を使用できますlift

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

この場合、tStateT MyStatemは ですMyMonad。たとえば、次のようになります。

foo :: StateT MyState MyMonad MyType
foo = do
  modify $ \s -> s+1
  lift $ doSomethingInMyMonad 42

MyMonad MyTypeモナドトランスフォーマーは、内部から型の値を返すという意味で「階層化」されていません。それはより文字通りの変換です:それらはモナドを、変換されたモナドでアクションを実行する能力を持つ新しいものに変えます。StateT s mしたがって、通常のState sモナドと考えることができますが、 を使用liftしてターン アクションを でアクションにm変換することもできますStateT s m

、 などの標準のMonad Transformer Library (mtl)トランスフォーマーを使用している場合は、実際に;を使用する必要はありません。スタックのどこかに適切なトランスフォーマーを持つモナドで機能します(スタックは、 のような変換されたモナドの単なるタワーです。)StateTReaderTliftmodifyaskStateT s (ReaderT r IO)

さらに、一番下に大きなスタックがある場合は、アクションを任意の数のレイヤーIOに持ち上げるための便利な関数があります。IO

liftIO :: (MonadIO m) => IO a -> m a

、、などで動作liftIO (putStrLn "Hello, world!")します。IOStateT Int IOContT r (WriterT [String] IO)

(追記として、これfooは実際には関数ではありません。より正確な用語は、アクションまたは計算です。)

于 2012-01-20T15:35:28.963 に答える