我遇到了“Ambiguous occurrence”错误
好的,让我们尝试你发布的代码。
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
的缩写)。但是,您可以使用info命令:
> :i State
type Control.Monad.Trans.State.State s =
StateT s Identity :: * -> *
type Main.State s = StateT s Identity :: * -> *
因此,您可以看到,您的(Main)类型别名与您从Control.Monad.Trans.State导入的类型别名是多余的。解决方案?只需不定义您的类型别名。
编辑:以上内容旨在澄清一些误解。在此回答您的实际问题。
“状态单子”在哪里?
Haskell库中定义了许多状态单子。最受欢迎的是来自transformers包的Control.Monad.Trans.State。还有一个monadlib版本的State和完全不同的MonadState类(在mtl包中),它是对具有某种状态概念的任何单子进行获取和设置操作的一对。
我该如何使用它?
嗯,您导入模块并可以运行StateMonadicOperation initialState:
> runState (mapM (\x -> state $ \s -> (x,s+x)) [1..4]) 9
([1,2,3,4],19)
如果你有具体的问题,可以在stackoverflow上找到很多关于状态单子的问题。
我想知道这个是否存在?
这取决于你问题中的 it
。虽然有一个 State
类型构造器,但没有 State
数据构造器。
使用 :i get 命令,我发现 MonadState,这是 State 的新实现吗?
不是。状态单子 State
在变换器中定义为:
type State s = StateT s Data.Functor.Identity.Identity :: * -> *
newtype StateT s (m :: * -> *) a
= StateT {runStateT :: s -> m (a, s)}
有一个带有数据构造函数和类型别名的transformer和身份monad。
相比之下,MonadState只是获取和设置值能力的抽象:
class Monad m => MonadState s (m :: * -> *) | m -> s where
get :: m s
put :: s -> m ()
State
类型构造器不再存在。相反,您可以使用位于MonadState
类型类中的state
函数。更多信息请查看Control.Monad.State.Lazy。 - ReduState
不再存在了,但State
单子仍然存在;只不过现在它是通过另一个StateT
单子来定义,而不是作为自己单独的单子实现。这个新的状态单子位于Control.Monad.Trans.State
模块中,在transformers
库中。编辑: 我刚才注意到你已经知道了Control.Monad.Trans.State
—— 对于冗余的评论感到抱歉! - bradrn