我想在Haskell写一个小游戏,并且有相当数量的状态需要传递。我想尝试隐藏状态monad使用状态monad隐藏显式状态
现在我遇到了一个问题:功能,采取国家和一个参数很容易写入工作在状态单子。但也有一些函数只是将状态作为参数(并返回一个修改的状态,或者可能是其他的)。
在我的代码的一部分,我有这样一行:
let player = getCurrentPlayer state
我想它不会采取状态,而不是写
player <- getCurrentPlayerM
目前,它的实现看起来像这样
getCurrentPlayer gameState =
(players gameState) ! (on_turn gameState)
它似乎很简单,使它在国家单体中的工作,通过这样写:
getCurrentPlayerM = do state <- get
return (players state ! on_turn state)
然而,这引起ghc的投诉!它说,没有使用“get”引起的(MonadState GameState m0)实例。我已经重写了非常相似的功能,但并不是在其国家单子形式无参,等等预感,我重写这样的:
getCurrentPlayerM _ = do state <- get
return (players state ! on_turn state)
果然,它的工作原理!但我当然必须将其称为getCurrentPlayerM(),并且我觉得这样做有点愚蠢。传递一个论点是我首先想避免的!
一个额外的惊喜:在ghci中寻找它的类型,我得到
getCurrentPlayerM :: MonadState GameState m => t -> m P.Player
,但如果我尝试设置,明确在我的代码,我得到另一个错误:“非类型变量参数的约束MonadState GameState m“并提供语言扩展以允许它。我想这是因为我的GameState是一个类型而不是一个类型类,但是为什么它在实践中被接受了,但是当我尝试对它进行明确的时候我并没有更加困惑。
所以总结起来:
- 为什么我不能写在单子国家职能零元?
- 为什么我不能声明我的解决方法函数实际上具有的类型?
明确说明我想要哪个monad似乎是正确的解决方案。是的,我已经遇到了记录中的记录问题,并且读了一些关于Lenses的内容(其中包括我在这里搜索答案的时候,它似乎被推荐了很多!)。谢谢,优秀的解释! –