Haskell 函子隐含定律
“类似的论点还表明,任何满足第一定律 (fmap id = id) 的 Functor 实例将自动满足实际上,这意味着只需检查第一定律(通常通过非常简单的归纳)即可确保 Functor 实例有效。”
如果是这样的话,为什么我们还要提到第二函子定律呢?
Law 1: fmap id = id
Law 2: fmap (g . h) = (fmap g) . (fmap h)
Typeclassopedia says:
"A similar argument also shows that any Functor instance satisfying the first law (fmap id = id) will automatically satisfy the second law as well. Practically, this means that only the first law needs to be checked (usually by a very straightforward induction) to ensure that a Functor instance is valid."
If this is the case, why do we even mention the second functor law?
Law 1: fmap id = id
Law 2: fmap (g . h) = (fmap g) . (fmap h)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
虽然我无法给出证明,但我相信这说明的是由于参数化,只要第一定律成立,类型系统就强制执行第二定律。指定这两个规则的原因是,在更一般的数学设置中,您可能有一些类别 C,其中完全可以定义从 C 到其自身的“映射” (即 Obj(C) 和 Hom(C 上的一对内函数) 分别) 遵守第一条规则但未能遵守第二条规则,因此无法构成函子。
请记住,Haskell 中的函子是 Hask 类别上的endofunctor,甚至不是所有在数学上被视为 Hask 上的endofunctor 的东西都可以表达在 Haskell 中...参数多态性的约束排除了能够指定一个对于它映射的所有对象(类型)行为不统一的函子。
基于此帖子,普遍的共识似乎是第二个对于 Haskell Functor 实例,定律遵循第一个定律。爱德华·克梅特 说,
While I can't give a proof, I believe what this is saying is that due to parametricity, the type system enforces the second law as long as the first law holds. The reason to specify both rules is that in the more general mathematical setting, you might have some category C where it is perfectly possible to define a "mapping" from C to itself (i.e. a pair of endofunctions on Obj(C) and Hom(C) respectively) which obeys the first rule but fails to obey the second rule, and therefore fails to constitute a functor.
Remember that
Functor
s in Haskell are endofunctors on the category Hask, and not even everything that would mathematically be considered an endofunctor on Hask can be expressed in Haskell... the constraints of parametric polymorphism rule out being able to specify a functor which does not behave uniformly for all objects (types) which it maps.Based on this thread, the general consensus seems to be that the second law follows from the first for Haskell
Functor
instances. Edward Kmett says,使用
seq
,我们可以编写一个满足第一条规则但不满足第二条规则的实例。我们可以验证这满足第一定律:
但是,它违反了第二定律:
也就是说,我们通常会忽略这种病态的情况。
Using
seq
, we can write an instance which satisfies the first rule but not the second one.We can verify that this satisfies the first law:
However, it breaks the second law:
That said, we usually ignore such pathological cases.
我想说第二定律没有被提及是出于有效性原因,而是作为一个重要的属性:
(我不明白为什么第一定律暗示第二定律,但我不是一个熟练的 Haskeller - 当你知道发生了什么时,它可能是显而易见的)
I'd say the second law is not mentioned for validity reasons, but rather as an important property:
(I can't see why this first law implies the second law, but I'm not a skilled Haskeller - its probably obvious when you know what's going on)
似乎最近才意识到法则 2 源自法则 1。因此,在最初编写文档时,它可能被认为是一个独立的要求。
(就我个人而言,我并不相信这个论点,但由于我自己没有时间弄清楚细节,所以我在这里给予它怀疑的好处。)
It seems that it was realized quite recently that law 2 follows from law 1. Thus, when the documentation was originally written, it was probably thought to be an independent requirement.
(Personally, I'm not convinced by the argument, but since I haven't had the time to work out the details myself, I'm giving it the benefit of doubt here.)