原问题
Haskell的最新版本(> 7.4.2?)附带一个mtl包,该包本身不再提供状态构造函数,而是提供状态函数。
这打乱了维基图书页面上的州的例子:http://en.wikibooks.org/wiki/Haskell/Understanding_monads/State
谁能展示一下如何修改标题“介绍状态”后面的示例?这就是小函数rollDie和rollDice。
页面前面有一个注释框,靠近标题“State Monad的定义”,大体描述了要做什么,但对我来说太含糊了。
此外,我也不太清楚导入和包是如何工作的,因此与此示例相关的一件可能的事情可能是指定需要什么导入,因为它们也可能已经发生了变化。
谢谢!
源代码
------- 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年前是这样。
发布于 2013-02-22 12:19:11
上面的代码只有一个问题
Control.Monad ===> Control.Monad.State只有当你有像这样的东西时,变化才会真正影响你
foo :: State Int Int
foo = State $ \a -> (a, a) -- This is an error但是修复它很容易:
foo :: State Int Int
foo = state $ \a -> (a, a)类型构造函数State仍然存在,它只是为了支持state而隐藏了数据构造函数。这有点让人困惑,因为它们的名字都是一样的。
发布于 2013-02-22 12:16:51
使用State类型同义词可以很好地编译代码。你只需要
import Control.Monad.Statehttps://stackoverflow.com/questions/15016115
复制相似问题