繁体   English   中英

一个元组(monad,state)?

[英]A monad of tuples (monad, state)?

我试图使用Monads编写Haskell“猜数字”游戏程序,但我陷入了困境:
我尝试了简单的state monad:

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

),欢迎任何意见和参考,谢谢。
PS I对数据类型SM和类型构造函数SMN使用了不同的表示法,以便区分它们。

(>>=)的类型是:

Monad m => m a -> (a -> m b) -> m b

由于您正在为SM编写实例,因此实例中的绑定类型为

SM a -> (a -> SM b) -> SM b

注意, ab都是完全不受限制的类型变量。 这意味着无论我选择放入哪种类型,您提供的任何实现都必须有效。 特别是,我可以为ab选择Int

SM Int -> (Int -> SM Int) -> SM Int

现在很明显为什么您的实现不好:它会尝试将Int视为单声道操作,然后对其进行调用(>>=)

如果您想在绑定中执行单子操作,则必须以某种方式谈论单子类型。 例如,一种标准方法是定义

data SMT m a = SMT (S -> m (a, S))

并给出一个实例,例如:

instance Monad m => Monad (SMT m) where -- ...

如果愿意,可以通过将Identity monad用作嵌套monad来恢复正常SM

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM