haskell - 这个 Monad Stack 函数的名称是什么?

标签 haskell monads monad-transformers state-monad

我在 State monad 中有一堆有状态的函数。在程序中的某个时刻,需要一些 IO 操作,所以我将 IO 包装在 StateT 中,得到如下一对类型:

mostfunctions :: State Sometype a
toplevel :: StateT Sometype IO a

为了简单起见,我不想将 IO 上下文传递到主函数集中,并且我想避免将它们包装在 monad 堆栈类型中。但是为了从顶层函数调用它们,我需要类似于电梯的东西,但我并不是想从内部单子(monad)中提升一个值。相反,我想将 StateT monad 中的状态转换为 State monad 中的等价物。为此,我有以下内容:
wrapST :: (State Sometype a) -> StateT Sometype IO a
wrapST f = do s <- get
              let (r,s2) = runState f s 
              put s2
              return r

然后这习惯于交错如下内容:
toplevel = do liftIO $ Some IO functions
              wrapST $ Some state mutations
              liftIO $ More IO functions
              ....

这似乎是一个相当明显的代码块,所以我想知道这个函数是否有一个标准名称,并且它已经在标准库的某个地方实现了?我试图使描述保持简单,但显然这延伸到将一个变压器从堆栈中拉出,将包装的值转换为变压器类型的表亲,跳过堆栈中下面的单子(monad),然后将结果推回结束。

最佳答案

重构代码以使用类型 StateT SomeType m a 可能是个好主意而不是 State SomeType a ,因为第一个与任意 monad 堆栈兼容。如果你想这样改变它,你不需要函数 wrapST不再,因为您可以直接调用有状态函数。

好的。假设你有一个函数 subOne :: Monad m => State Int Int :

subOne = do a <- get
            put $ a - 1
            return a

现在,将所有函数的类型从 State SomeType a 更改为至StateT SomeType m a , 离开 m照原样。这样,您的函数可以在任何一元堆栈上运行。对于那些需要 IO 的函数,您可以指定底部的 monad 必须是 IO:
printState :: MonadIO m => StateT Int m ()
printState = do a <- get
             liftIO $ print a

现在,应该可以同时使用这两个功能:
-- You could use me without IO as well!
subOne :: Monad m => StateT Int m ()
subOne = do a <- get
            put $ a - 1

printState :: MonadIO m => StateT Int m ()
printState = do a <- get
             liftIO $ print a

toZero :: StateT Int IO ()
toZero = do subOne     -- A really pure function
            printState -- function may perform IO
            a <- get
            when (a > 0) toZero

PS:我使用的是 GHC 7,一些库在中途改变了,所以在 GHC 6 上可能会有点不同。

关于haskell - 这个 Monad Stack 函数的名称是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5968018/

相关文章:

haskell - 在我自己的 Queue 类型中包装 Data.Sequence 有什么问题吗?

haskell - 用 `catchError`写一串 `(<|>)` -s吗?

haskell - ST monad 是如何工作的?

haskell - 向量的单次创建(或 : can someone type annotate this for me? )

haskell - 提升、返回和变压器类型构造函数

haskell - 如何通过可能的输出查找列表中的最大元素

scala - 应用仿函数如何与并行算法联系起来? (斯卡拉和斯卡拉兹)

Scalaz - 结合 List 和 State Monad 进行理解

haskell - monad 变压器何时需要提升?

algorithm - 帮助我找到我在 Haskell 中对 Project Euler #12 的解决方案的问题