[英]Data constructor not in scope despite copy-pasting exact code and importing module
我正在尝试运行 Haskell 在线书籍中最简单的示例之一,您可以在其中实现有状态的 function 对一堆数字进行建模。 我正在使用的示例中的代码是 ( http://learnyouahaskell.com/for-a-few-monads-more#state ):
import Control.Monad.State
type Stack = [Int]
pop :: State Stack Int
pop = State $ \(x:xs) -> (x,xs)
push :: Int -> State Stack ()
push a = State $ \xs -> ((),a:xs)
然而,当尝试在 Prelude 中加载它时,我得到:
state.hs:6:7: error:
Data constructor not in scope:
State :: ([a0] -> (a0, [a0])) -> State Stack Int
|
6 | pop = State $ \(x:xs) -> (x,xs)
| ^^^^^
state.hs:9:10: error:
Data constructor not in scope:
State :: ([Int] -> ((), [Int])) -> State Stack ()
|
9 | push a = State $ \xs -> ((),a:xs)
| ^^^^^
Failed, no modules loaded.
我错过了什么??? 这个例子有什么问题吗?
我只是希望简单地加载模块而不会出现错误。 不知道出了什么问题。
有点令人惊讶的是, Control.Monad.State
模块不包含名为State
的数据构造函数。 如果它简单地定义就是这种情况
newtype State' s a = State { runState :: s -> (a,s) }
– 它曾经在mtl
库的版本 1 中执行过,但现在不再执行了。 从 2.0 版本开始,该模块只导出一个名为State
的类型同义词,它实际上是从Control.Monad.Trans.State
重新导出的,因此实现:
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
type State s = StateT s Identity
Identity
monad 使这个行为使得m (a,s)
本身与简单(a,s)
同构,所以最终StateT s Identity a
确实与State' sa
同构。 然而,它更通用: StateT
是一个monad 转换器,也可以堆叠在其他 monadic 操作之上,例如IO
。
所以你不能使用State
值构造函数,但你可以使用state
,它的行为与State
在mtl-1.1
中的行为完全相同。 (除非你不能对其进行模式匹配,但你仍然可以使用runState
。)
pop :: State Stack Int
pop = state $ \(x:xs) -> (x,xs)
push :: Int -> State Stack ()
push a = state $ \xs -> ((),a:xs)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.