haskell - 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) }
但我还需要一些其他功能,例如put
,get
...它们在哪里。
使用:i get
,我发现MonadState
,这是新的工具 State
吗?
解决方案
我得到模棱两可的发生
真的,让我们试试你发布的代码..
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
所以你看,你的 ( Main
s) 类型别名与你从中导入的类型别名是多余的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 上找到很多状态单子问题。
我想知道它是否存在?
这取决于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 ()
推荐阅读
- javascript - svg d3js .drag(...).origin 不是函数
- batch-file - 将参数作为文件的模式传递
- mysql - MySqlException:对于带有游标的存储过程,子查询返回多于 1 行
- json - Angular 发布请求失败,错误为 500
- vba - VBA 填充名称
- html - 如何使弹性项目的高度随内容扩展并阻止它溢出?
- wordpress - 如何将打开的图形元标记添加到 WordPress wp-login 页面?
- node.js - 具有 ASG 和 ELB (bitbucket) 的 AWS CD/CI 管道
- java - 来自 Keycloak 的 JWT 访问令牌的 Java 离线验证
- c# - 在没有 foreach 的情况下迭代 JObject