【发布时间】:2015-02-21 15:37:14
【问题描述】:
我正在尝试使用 Monads 编写一个 Haskell“猜数”游戏程序,但我被卡住了:
我尝试了简单的状态单子:
data SM a = SMN (S -> (a, S))
instance Monad SM where
SMN c1 >>= fc2 = SMN (\s0 -> let (r, s1) = c1 s0 in
let SMN c2 = fc2 r in
c2 s1)
并且我需要在元组(a,S)的“IO端”执行IO任务,也就是说,我尝试做类似的事情:
SMN c1 >>= fc2 = SMN (\s0 -> let (r, s1) = c1 s0 in
let SMN c2 = fc2 r in
let (r1, s2) = c2 s1 in
let r2 = r1 >>= (\_ -> r) in
(r2, s2))
简而言之,我想定义的绑定运算符与原始状态 monad 相同,只是我们绑定了 r1 和接受 r 参数的常量函数(以便将两个动作链接在一起)。但是 ghc 告诉我 a 是一个刚性类型变量......这是什么意思?我不能在一个绑定运算符中使用另一个绑定运算符?
如果是这样,那么有没有办法实现这样的绑定运算符?怎么样?
因为我是 Haskell 的新手(我想我可能有关于函数的符号错误
\_ -> r
),欢迎任何意见和参考,在此先感谢。
附言我对数据类型 SM 和类型构造函数 SMN 使用了不同的符号,以便区分它们。
【问题讨论】:
-
代码很混乱。你能解释一下你想要做什么吗?在我看来,您正在尝试构建类似
StateT s IO a的东西。您可以在Control.Monad.Trans.State.Strict和Control.Monad.Trans.State.Lazy中找到它的变体。但我不能肯定地说,因为我看不懂你的代码。 -
@dfeuer 我想在元组的两个部分中分离 monad 动作和状态记录: (monad, state),这样我可以在需要时调用 fst 和 snd 来分离它们和执行一些合适的动作。我不知道怎么解释清楚,也许我写完代码后可以展示这个monad的用法,然后我这里要构建什么就清楚了。
标签: haskell io monads state-monad