实现状态monad时数据构造函数错误?

Bab*_*ham 2 monads haskell

我在这里经历状态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)

我错过了一些基本的东西吗?

Ale*_*lec 8

不,你不是.这个教程简化了一些事情(或者它可能只是过时了 - 我不会回过头来知道这两个中的哪一个)已经过时了.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)