这个Monad Stack函数的名字是什么?

我在国家monad中有一堆有状态的函数。 在程序中的某个地方需要一些IO操作,所以我在一个StateT中包装了IO,得到了一对类型:

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

为了简单起见,我不想将IO上下文传递到主函数集中,我想避免将它们封装在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
              ....

它看起来像一个相当明显的代码块,所以我想知道这个函数是否有标准名称,并且它已经在标准库中的某处实现了? 我尽量保持描述简单,但显然这延伸到从堆栈中拉出一个变压器,将包裹的值转换为变压器类型的表亲,跳过堆栈中下面的单元,然后将结果推回到结束。


重构代码以使用类型StateT SomeType ma代替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 ma ,使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可能有点不同。


更直接的回答你的问题:功能hoist完全按照更通用的方式描述你正在描述的内容。 用法示例:

import Control.Monad.State
import Data.Functor.Identity
import Control.Monad.Morph

foo :: State Int Integer
foo = put 1 >> return 1

bar :: StateT Int IO Integer
bar = hoist (return . runIdentity) foo

hoistMFunctor类的一部分,它是这样定义的:

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

大多数monad ContT都有实例,但不是ContT

链接地址: http://www.djcxy.com/p/77359.html

上一篇: What is the name of this Monad Stack function?

下一篇: Why is ListT monad transformer considered buggy