状态'的数据构造函数在哪里?

时间:2014-06-08 04:50:44

标签: haskell monads

在阅读了几本关于Haskell状态monad的教程后,我想自己尝试一下。我读过的教程声称Control.Monad.State提供了以下定义:

newtype State s a = State { runState :: s -> (a,s) }  

但是,我似乎无法找到State数据构造函数:

Prelude> import Control.Monad.State
Prelude Control.Monad.State> :t State

<interactive>:1:1:
    Not in scope: data constructor `State'
    Perhaps you meant `StateT' (imported from Control.Monad.State)

我还尝试了对State进行Hoogle搜索,但未找到任何具有预期类型的​​数据构造函数。

State构造函数去了哪里?它曾经存在过吗?或者我只是在错误的地方寻找?基本上我想知道我需要做什么来创建状态monad。

3 个答案:

答案 0 :(得分:30)

它不再存在。不幸的是,这使得Web上的许多Haskell资源都过时了。

要创建值,您只需使用state函数:

state :: (s -> (a, s)) -> State s a

runState,曾经是State的字段,现在只是一个普通的函数,但它的工作原理和以前一样。

State已根据StateT monad变换器重写:

type State s = StateT s Identity

StateT本身有一个构造函数StateT,其功能与旧的State构造函数非常相似:

newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }

唯一的区别是有一个额外的参数m。这只是一个插槽,您可以在其中添加任何其他monad,StateT然后使用状态处理功能进行扩展。当然,要重新获得State的旧功能,您只需将m设置为Identity,这样做无效。

newtype Identity a = Identity { runIdentity :: a }

答案 1 :(得分:14)

前一段时间MTL已从

切换
newtype State s a = State ...

type State s = StateT s Identity

因为否则我们不得不复制每个monad及其变换器的逻辑。相反,您现在可以使用state函数

state :: (s -> (a, s)) -> State s a

可悲的是,RWHLYAH在这方面都已过时:(

答案 2 :(得分:4)

我正在通过Learn Has a Haskell(LYAH)进行学习,我认为我会发布在http://learnyouahaskell.com/for-a-few-monads-more#state(第13章,“有状态的有状态计算”一节)中找到的示例代码的工作版本。 >

不再起作用的代码:

import Control.Monad.State  

pop :: State Stack Int  
pop = State $ \(x:xs) -> (x,xs)  

push :: Int -> State Stack ()  
push a = State $ \xs -> ((),a:xs)  

修改后的代码可以正常工作:

import Control.Monad.State 

pop :: State Stack Int
-- note the change from "State" to "state"
pop = state $ \(x:xs) -> (x,xs)

push :: Int -> State Stack ()
push a = state $ \xs -> ((), a:xs)

“ stackManip”函数按原样工作:

stackManip :: State Stack Int  
stackManip = do  
    push 3  
    a <- pop 
    pop