Put的MonadFix实例

时间:2012-06-17 02:16:49

标签: haskell typeclass monadfix

一个简单的问题,我希望:binary包定义了两种类型Get and Put。前者本质上是一个州的monad,而后者本质上是一个作家。州和作家都有合理的MonadFix个实例,所以我希望GetPut也会这样。

GetPut没有。那么,是否可以为MonadFix定义适当的Put实例(真的是PutM)?

一个更普遍的问题是:通常如何验证类型类实例是否真正满足该类型类的规律?

2 个答案:

答案 0 :(得分:7)

正如您在二进制包(Data.Binary.Put:71)的源代码中所看到的,构建器中用于monadic值的数据结构是严格的。由于从monad中提取值必须强制找到值的结构,如果构建器依赖于输入,这将导致无限循环。

data PairS a = PairS a !Builder
newtype PutM a = Put { unPut :: PairS a }

所以你可以编写一个MonadFix实例,但是你无法用它做任何有用的事情。但是我认为你无论如何都不能对MonadFix做任何有用的事情,至少没有你用普通的fix做的事情,因为PutM monad基本上是{{ 1}}(但有专门的实现)。

至于你的第二个问题,它与第一个问题无关,所以你应该把它作为一个单独的问题。

答案 1 :(得分:1)

以下是对第二个问题的回答以及对Daniel的评论的后续跟进。您手动验证法律,我会使用Functor的{​​{1}}法律示例:

Maybe

显然我可以跳过很多这些步骤,但我只想拼出完整的证据。证明这些规律一开始是困难的,直到你掌握了它们,所以开始缓慢和迂腐是一个好主意,然后一旦你变得更好,你可以开始结合步骤,甚至在一段时间后做一些更简单的事情的。