首页 > 解决方案 > Haskell 中的 State Monad 在哪里,我该如何使用它?

问题描述

我正在学习 State Monad,并被告知它不再存在,第一个问题是为什么 Haskell 删除它?

当我使用

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

type State s = StateT s Identity

我明白了

Ambiguous occurrence ‘State’
    It could refer to
       either ‘Control.Monad.Trans.State.State’
           or ‘Main.State’,

但是当我尝试时:t State,我什么也没找到。这是自相矛盾的,我想知道它是否存在?

最后,我自己写

newtype State s a = State { runState :: s -> (a, s) }

但我还需要一些其他功能,例如putget...它们在哪里。

使用:i get,我发现MonadState,这是新的工具 State吗?

标签: haskellmonadsmonad-transformers

解决方案


我得到模棱两可的发生

真的,让我们试试你发布的代码..

cat <<EOF >umi.hs
import Data.Functor.Identity
import Control.Monad.Trans.State

type State s = StateT s Identity
EOF
ghci umi.hs

我们得到

Ok, one module loaded.

所以这实际上很好。我怀疑你有更多的代码试图使用State,但它是模棱两可的,因为你已经导入了 aState并且不需要定义你自己的State类型。

当我尝试 :t 状态时,我什么也没找到。这是自相矛盾的

当你尝试时:t State,你得到的不仅仅是什么,你会得到:

:t State

<interactive>:1:1: error:
    • Data constructor not in scope: State

仔细阅读,它说的是“数据构造函数”而不是“类型”或“类型构造函数”。您无法检查类型的类型(:t是 short of :type)。但是,您可以使用 info:

> :i State
type Control.Monad.Trans.State.State s =
  StateT s Identity :: * -> *
        -- Defined in ‘Control.Monad.Trans.State.Lazy’

type Main.State s = StateT s Identity :: * -> *
        -- Defined at umi.hs:4:5

所以你看,你的 ( Mains) 类型别名与你从中导入的类型别名是多余的Control.Monad.Trans.State。解决方案?只是不要定义您的类型别名。

编辑:以上内容旨在消除一些误解。在这里回答您的实际问题。

状态单子在哪里

Haskell 库中定义了许多 State monad。最受欢迎的是您已经找到Control.Monad.Trans.State的包。transformers还有一个monadlibState 版本,以及完全不同的MonadState类(在mtl包中),它是任何具有某种状态概念的 monad 的一对 get 和 set 操作。

我该如何使用它?

那么你导入模块,你可以runState stateMonadicOperation initialState

> runState (mapM (\x -> state $ \s -> (x,s+x)) [1..4])  9
([1,2,3,4],19)

如果您有具体问题,可以在 stackoverflow 上找到很多状态单子问题。

我想知道它是否存在?

这取决于it您的问题。有一个State类型构造函数,但没有State数据构造函数。

使用:我明白了,我找到了 MonadState,这是 State 的新工具吗?

State,单子在变压器中定义为:

type State s = StateT s Data.Functor.Identity.Identity :: * -> *
newtype StateT s (m :: * -> *) a
  = StateT {runStateT :: s -> m (a, s)}

所以有一个带有数据构造函数的转换器以及转换器和标识单子的类型别名。

相比之下,MonadState 只是获取和设置值的能力的抽象:

class Monad m => MonadState s (m :: * -> *) | m -> s where
  get :: m s
  put :: s -> m ()

推荐阅读