我在这里经历状态monad ,我正在尝试实现:
import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State
type Stack = [Int]
pop :: State Stack Int
pop = State $ (x : xs) -> (x, xs)
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
"Data constructor not in scope:
State :: ([t0] -> (t0, [t0])) -> State Stack Int
Perhaps you meant one of these:
‘StateT’ (imported from Control.Monad.State),
variable ‘state’ (imported from Control.Monad.State)"
Run Code Online (Sandbox Code Playgroud)
我错过了一些基本的东西吗?
不,你不是.这个教程简化了一些事情(或者它可能只是过时了 - 我不会回过头来知道这两个中的哪一个)已经过时了.Control.Monad.State定义monad 变换器 StateT.它还导出一个类似于教程教你的简单类型同义词
type State s a = StateT s Identity a
Run Code Online (Sandbox Code Playgroud)
但是,这确实意味着构造函数不是State,它是StateT(并且它具有通用签名).值得庆幸的是,你现在不需要太担心.
State,您可以使用该state函数并假装它具有签名state :: (s -> (a,s)) -> State s a(实际上,它具有更一般的签名 - 您在错误消息中遇到).State,只需使用runState :: State s a -> s -> (a,s)而不是模式匹配.从你给出的例子:
import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State
type Stack = [Int]
pop :: State Stack Int
pop = state $ \(x : xs) -> (x, xs)
Run Code Online (Sandbox Code Playgroud)