我正在学习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) }
但是我还需要其他一些功能,例如put
,get
...它们在哪里。
使用:i get
,我发现MonadState
,这是State
的新工具吗?
答案 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 ()