首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >维基百科中的Haskell状态示例:根据当前Haskell修复?

维基百科中的Haskell状态示例:根据当前Haskell修复?
EN

Stack Overflow用户
提问于 2013-02-22 11:00:07
回答 2查看 655关注 0票数 2

原问题

Haskell的最新版本(> 7.4.2?)附带一个mtl包,该包本身不再提供状态构造函数,而是提供状态函数。

这打乱了维基图书页面上的州的例子:http://en.wikibooks.org/wiki/Haskell/Understanding_monads/State

谁能展示一下如何修改标题“介绍状态”后面的示例?这就是小函数rollDie和rollDice。

页面前面有一个注释框,靠近标题“State Monad的定义”,大体描述了要做什么,但对我来说太含糊了。

此外,我也不太清楚导入和包是如何工作的,因此与此示例相关的一件可能的事情可能是指定需要什么导入,因为它们也可能已经发生了变化。

谢谢!

源代码

代码语言:javascript
复制
------- Adding code for ghci01.hs-------

-- http://en.wikibooks.org/wiki/Haskell/Understanding_monads/State
-- Introducing State heading and below

import Control.Monad
import System.Random

type GeneratorState = State StdGen

rollDie :: GeneratorState Int
rollDie = do generator <- get
             let (value, newGenerator) = randomR (1,6) generator
             put newGenerator
             return value

-- Test rollDie
-- evalState rollDie (mkStdGen 0)

rollDice :: GeneratorState (Int, Int)
rollDice = liftM2 (,) rollDie rollDie

-- Test rollDice
-- evalState rollDice (mkStdGen 666)

------- In GHCi --------
ghci> :l dice01.hs
[1 of 1] Compiling Main             ( dice01.hs, interpreted )
dice01.hs:7:23: Not in scope: type constructor or class `State'
dice01.hs:10:27: Not in scope: `get'
dice01.hs:12:14: Not in scope: `put'
Failed, modules loaded: none.

附录

对于那些在这里跌跌撞撞的人:

这个问题的主要主题围绕着不能正常工作的示例代码,以及上面提到的wikibooks页面上的Note框中的警告。该框告诉我们,对于2.0.0.0以上的MTL版本,由于Control.Monad.State中的更改,一些示例代码将无法工作。

我的测试涉及Haskell Platform 2012.4.0.0,其中包括GHC7.4.2,以及基于mtl.cabal文件的MTL,我后来发现它是1.1.1.1。因此,Note的警告不应该适用,但是示例代码仍然不起作用。answers在这里建议的更改(将导入Control.Monad更改为Control.Monad.State)确实解决了这个问题。但显然,这是在修复一个与早期的一些更改有关的问题,而不是注释中引用的MTL 2.x。

从那以后,我查看了GHC 7.6.2的源代码,但在那里我根本找不到MTL库。相反,与状态相关的文件在libraries/transformers/Control/Monad/Trans/State.中然后我走了一系列令人困惑的弯路,包括目前没有Haskell平台使用7.4.2之后的GHC (即: no 7.6.2)的问题。

然后我找到了指向这个堆栈溢出的MTL文档(http://www.haskell.org/haskellwiki/Monad_Transformer_Library) Q&A:mtl, transformers, monads-fd, monadLib, and the paradox of choice ...这在某种程度上解释了很多事情,至少在2-3年前是这样。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-22 12:19:11

上面的代码只有一个问题

代码语言:javascript
复制
Control.Monad ===> Control.Monad.State

只有当你有像这样的东西时,变化才会真正影响你

代码语言:javascript
复制
foo :: State Int Int
foo = State $ \a -> (a, a) -- This is an error

但是修复它很容易:

代码语言:javascript
复制
foo :: State Int Int
foo = state $ \a -> (a, a)

类型构造函数State仍然存在,它只是为了支持state而隐藏了数据构造函数。这有点让人困惑,因为它们的名字都是一样的。

票数 7
EN

Stack Overflow用户

发布于 2013-02-22 12:16:51

使用State类型同义词可以很好地编译代码。你只需要

代码语言:javascript
复制
import Control.Monad.State
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15016115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档