Haskell 函子隐含定律

发布于 2024-12-18 17:58:24 字数 321 浏览 3 评论 0原文

Typeclassopedia 说:

“类似的论点还表明,任何满足第一定律 (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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

那伤。 2024-12-25 17:58:24

虽然我无法给出证明,但我相信这说明的是由于参数化,只要第一定律成立,类型系统就强制执行第二定律。指定这两个规则的原因是,在更一般的数学设置中,您可能有一些类别 C,其中完全可以定义从 C 到其自身的“映射” (即 Obj(C)Hom(C 上的一对内函数) 分别) 遵守第一条规则但未能遵守第二条规则,因此无法构成函子。

请记住,Haskell 中的函子是 Hask 类别上的endofunctor,甚至不是所有在数学上被视为 Hask 上的endofunctor 的东西都可以表达在 Haskell 中...参数多态性的约束排除了能够指定一个对于它映射的所有对象(类型)行为不统一的函子。

基于此帖子,普遍的共识似乎是第二个对于 Haskell Functor 实例,定律遵循第一个定律。爱德华·克梅特

给定 fmap id = id, fmap (f . g) = fmap f . fmap g 来自 free
fmap定理。

这是很久以前在一篇论文中作为旁白发表的,但我忘了在哪里。

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 Functors 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,

Given fmap id = id, fmap (f . g) = fmap f . fmap g follows from the free
theorem for fmap.

This was published as an aside in a paper a long time back, but I forget where.

2024-12-25 17:58:24

使用seq,我们可以编写一个满足第一条规则但不满足第二条规则的实例。

data Foo a = Foo a
    deriving Show

instance Functor Foo where
    fmap f (Foo x) = f `seq` Foo (f x)

我们可以验证这满足第一定律:

fmap id (Foo x)
= id `seq` Foo (id x)
= Foo (id x)
= Foo x

但是,它违反了第二定律:

> fmap (const 42 . undefined) $ Foo 3
Foo 42
> fmap (const 42) . fmap undefined $ Foo 3
*** Exception: Prelude.undefined

也就是说,我们通常会忽略这种病态的情况。

Using seq, we can write an instance which satisfies the first rule but not the second one.

data Foo a = Foo a
    deriving Show

instance Functor Foo where
    fmap f (Foo x) = f `seq` Foo (f x)

We can verify that this satisfies the first law:

fmap id (Foo x)
= id `seq` Foo (id x)
= Foo (id x)
= Foo x

However, it breaks the second law:

> fmap (const 42 . undefined) $ Foo 3
Foo 42
> fmap (const 42) . fmap undefined $ Foo 3
*** Exception: Prelude.undefined

That said, we usually ignore such pathological cases.

思念满溢 2024-12-25 17:58:24

我想说第二定律没有被提及是出于有效性原因,而是作为一个重要的属性:

第一定律规定将恒等函数映射到每个项目上
在容器中没有任何影响。第二个说映射一个
容器中每个项目的两个函数的组合是
与首先映射一个函数,然后映射另一个函数相同。
--- 类型分类百科

(我不明白为什么第一定律暗示第二定律,但我不是一个熟练的 Haskeller - 当你知道发生了什么时,它可能是显而易见的)

I'd say the second law is not mentioned for validity reasons, but rather as an important property:

The first law says that mapping the identity function over every item
in a container has no effect. The second says that mapping a
composition of two functions over every item in a container is the
same as first mapping one function, and then mapping the other.
--- Typeclassopedia

(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)

遗忘曾经 2024-12-25 17:58:24

似乎最近才意识到法则 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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文