【问题标题】:What is this simple function called?这个简单的函数叫什么?
【发布时间】:2014-08-05 15:28:30
【问题描述】:

你已经看过下面的函数了吗?这叫什么?它有什么用?可以比StateT更通用地定义吗?

simpleFunction (StateT f) = StateT $ (\s -> return (f s, s))

顺便说一下,ghc 给它的类型是Monad n => StateT s m a -> StateT s n (m (a, s))

还有一个替代定义:

simpleFunction m = do
  s <- get
  mapStateT (\l -> return (l, s)) m

【问题讨论】:

  • 我怀疑这可以比State更通用地定义。
  • @leftaroundabout:好点。你对这种通用定义有什么建议吗?我已经相应地更新了问题。
  • 这是一个家庭作业问题;-?我问是因为如果它是一个(可能)有一个(有点简单)的答案。如果不是,我不确定是否有答案。
  • 你能激发这个问题吗?你能举例说明你想如何使用这个功能吗?
  • 我觉得这个功能不是很深。它只取当前状态,但除此之外 f s :: m (a, s) 完全独立于剩余的 StateT s n 计算。

标签: haskell functional-programming monads monad-transformers state-monad


【解决方案1】:

拥有两个像n (m a) 这样的单子通常不是很有用(组合可能不是单子等)。所以我想更有用的版本将是类型 (Monad m) =&gt; StateT s m a -&gt; StateT s m (a, s).

这可以推广到m 上的任意状态转换器:

import Control.Monad
import Control.Monad.State

f1 :: (MonadState s (t m), MonadTrans t, Monad m) => StateT s m a -> t m (a, s)
f1 (StateT f) = get >>= lift . f

由于我们唯一需要的是get,我们可以进一步概括为:

f2 :: (MonadTrans t, Monad m, Monad (t m)) => t m s -> StateT s m a -> t m (a, s)
f2 g (StateT f) = g >>= lift . f

如果您真的需要两个 monad,也许 MFunctor 会很有用 - 像 hoistgeneralize 这样的函数允许在 monad 之间切换。

【讨论】:

    【解决方案2】:

    simpleFunction 结构通过两件事参数化:一个 StateT monad 和一个函数 f。正如两个给定定义所示,simpleFunction 从 monad 内部获取状态,然后使用给定函数映射计算的返回值和最终状态。

    通过一个非常简单的示例来查看一个工作示例:

    import Control.Monad.State
    
    inc :: State Int Int
    inc = do
        n <- get
        put (n + 1)
        return n
    
    simpleFunction = do
                    s <- get
                    mapState (\l -> (l,s)) inc
    
    main = do
        print $ runState simpleFunction 1
    

    结果是:((1,2),1) 即((返回值,最终状态),初始状态)

    你看到的 simpleFunction 并不复杂。它可以与 StateT 以外的 monad 一起使用。在这种情况下,您必须实现自己的地图并获取。

    希望有用!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-13
      • 2013-03-20
      • 2011-04-07
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-08
      相关资源
      最近更新 更多