haskell - monad 变压器内 monad 的结果

标签 haskell monad-transformers

这是我第一次认识 Monad Transformers,所以答案可能很明显。

假设我在 StateT MyMonad MyType 类型的 do 块中,我想让另一个相同类型的函数修改状态并返回 MyMonad MyType 类型的值。我怎样才能做到这一点?我想的例子here在 guessSession 中显示它,但我似乎无法理解如何应用它!

最佳答案

如果要在 monad 转换器中使用底层 monad,可以使用 lift :

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

在这种情况下,tStateT MyState , 和 mMyMonad .因此,例如:
foo :: StateT MyState MyMonad MyType
foo = do
  modify $ \s -> s+1
  lift $ doSomethingInMyMonad 42

Monad 转换器不是“分层”的,因为您将返回类型为 MyMonad MyType 的值。从内部;这是一种更直接的转换:他们将一个 monad 变成一个新的,能够在转换后的 monad 中运行操作。所以,你可以想到StateT s m和普通的一样 State s monad,除了你也可以使用 liftm 中运行转弯 Action 进入行动 StateT s m .

如果您使用的是标准 Monad Transformer Library (mtl) 变压器,如 StateT , ReaderT等,您实际上不必使用 lift ;诸如 modifyask在堆栈中的某处使用正确的转换器在任何 monad 中工作。 (堆栈只是转换后的 monad 的塔,例如 StateT s (ReaderT r IO) 。)

此外,如果你有一个大堆栈 IO在底部,有一个提升IO的便利功能。操作任意数量的层:
liftIO :: (MonadIO m) => IO a -> m a

所以liftIO (putStrLn "Hello, world!")工作于 IO , StateT Int IO , ContT r (WriterT [String] IO) , 等等。

(作为附加说明,foo 这里实际上不是函数;更准确的术语是 Action 或计算。)

关于haskell - monad 变压器内 monad 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8943743/

相关文章:

haskell - 在其他一些 monad m1 中绑定(bind)一个 Monadic 值 (m2 a)

function - 如何在一个函数中找到具有多个输入的函数输出的最大值?

haskell - 如何用 View 模式语法编写这个 case 表达式?

git - 以编程方式确定 Git 分支状态的正确方法是什么?

haskell - 使用两个 monad 而不使用变压器

haskell - 如何正确地将 IO 添加到 attoparsec Parser?

haskell - 为什么 `coerce` 不隐式地将 Compose 应用于这些函数?

haskell - 如何规避 Haskell 中的现有实例(失败)?

haskell - 更多 rmonad 库?

haskell - 单子(monad)-tf : MonadReader instance for MonadState