Haskell:翻译成Monad

时间:2014-01-13 05:51:20

标签: haskell monads

为了更好地理解monad,我正在尝试自己编写。我从一些非monadic代码开始,可以使用一些帮助将其翻译成monad。

这个人为的例子的基本思路:对于计算的每个整数结果,我想跟踪该整数是偶数还是奇数。例如,在4 + 5 = 9中,我们可能会返回(9, Odd)

我希望能够使用>>=链接/撰写计算。例如:

return 1 >>= (+2) >>= (+5) >>= (+7) =result=> (15, Odd)

现在,我有以下非monadic代码:

data Quality = Odd | Even deriving Show

qual :: Integer -> Quality
qual x = case odd x of
             True -> Odd
             _ -> Even

type Qualifier = (Integer, Quality)

mkQ :: Integer -> Qualifier
mkQ x = (x, qual x)

plusQ :: Qualifier -> Qualifier -> Qualifier
plusQ (x, _) (y, _) = (x+y, qual (x+y))

chain = plusQ (mkQ 7) . plusQ (mkQ 5) . plusQ (mkQ 2)

有什么方法可以将上面的代码翻译成monad?我应该寻找哪些模式,以及它们的常见翻译模式是什么?

非常感谢提前!

2 个答案:

答案 0 :(得分:3)

我认为您真正想要的是Num的{​​{1}}个实例:

Qualified

这使您可以使用数学运算符直接操作data Qualified = Qualified { isEven :: Bool, value :: Integer } instance Num Qualified where (Qualified e1 n1) + (Qualified e2 n2) = Qualified e (n1 + n2) where e = (e1 && e2) || (not e1 && not e2) (Qualified e1 n1) * (Qualified e2 n2) = Qualified (e1 || e2) (n1 * n2) abs (Qualified e n) = Qualified e (abs n) signum (Qualified e n) = Qualified e (signum n) fromInteger n = Qualified (even n) n 数字:

Qualified

答案 1 :(得分:0)

从这一个中学到了很多东西。非常感谢您的时间和指导的评论员和答案!

总结:

解决方案:正如@n.m.和其他人评论说,这个例子没有一个好的monad翻译,因为我的原始模型不是类型泛型的。 Monad最适合类型通用计算模式。给出的好例子包括用于计算的Maybe monad可能会失败,以及State monad用于通过计算链存储和携带附件状态信息。

作为替代解决方案,@ GabrielGonzalez使用类型实例化提供了一个很好的解决方案。这保留了我原始模型的固有类型特异性,但扩展了它的界面以支持更多Num类型类接口并清理功能交互。

后续步骤:正如@weirdcanada和其他人推荐的那样,我想我会和State monad一起玩,看看如何将它应用到这个特定的例子中。然后我可以尝试一下自定义的Maybe as @ n.m。推荐使用。

再次,非常感谢那些评论和回应的人!

相关问题