Haskell的State Monad在哪里,如何使用?

时间:2019-10-20 16:24:27

标签: haskell monads monad-transformers

我正在学习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的新工具吗?

1 个答案:

答案 0 :(得分:9)

  

我出现歧义

真的,让我们尝试一下您发布的代码。

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的代码,但是它模棱两可,因为您已导入State且不需要定义自己的State类型。

  

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

当您尝试:t State时,您得到的不只是什么,而且还得到:

:t State

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

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

> :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

因此,您看到(Main)类型别名与从Control.Monad.Trans.State导入的类型别名是多余的。解?只是不要定义您的类型别名。

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

  

单子状态在哪里

Haskell库中定义了许多State monad。最受欢迎的是您已经找到的Control.Monad.Trans.State软件包中的transformers。还有一个monadlib版本的State和完全不同的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上找到很多状态monad问题。

  

我想知道它是否存在吗?

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

  

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

不。 State在变形金刚中将monad定义为:

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

因此,有一个带有数据构造函数的转换器,以及转换器和标识monad的类型别名。

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

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