`join` 和 `fmap join` 在 Haskell 中是否相等(从类别理论的角度来看)?

Are `join` and `fmap join` equals in Haskell (from Category theory point of view)?

我的问题来自 Haskell 中的单子第一定律:join . fmap join = join . join

Haskell/Category_theory中通过下图演示该法则:

令我感到困惑的是,这个示例使用的是类型的实例,而不是类型。因为类别 Hask 中的对象是类型,而不是它们的实例。

所以我尝试用类型重新绘制这个例子,这里是我得到的:

在这张图片中,两个箭头(joinfmap join)都指向 M(M(X))。这是同一个对象,还是有两个不同的M(M(X))?

I am confused by the fact that this example uses instances of types, not the types. Because the objects in category Hask are types, not their instances.

这个例子使用了一个 class 的实例,它本身就是一个 type


在Haskell中,是的,这是同一个对象(类型)。 Monad 类型 class 的实例必须是类型构造函数,并且类型构造函数是单射的。那么,应该很清楚

X = X   =>   M(X) = M(X)   =>   M(M(X)) = M(M(X))

这里要注意的是,这只意味着它们是相同的类型,而不是值。仅仅因为 fmap joinjoin 都可以将它们的类型专用于 Monad m => m (m (m a)) -> m (m a) 并不意味着它们做同样的事情。

他们没有。

ghci> (fmap join) [[[1],[2],[3]]]
[[1,2,3]]         
ghci> join [[[1],[2],[3]]]
[[1],[2],[3]]

并非所有类别的图最终都必须是通勤图。 :)

从图中可以看出,fmap joinjoin产生不同相同类型的值].因此,它们并不相同,即使它们的 组合 join 最终产生相同的值。

在范畴论中,epimorphism 是一个态射 g,使得 f1 . g == f2 . g 也蕴含 f1 == f2。在这种情况下,我们可以看到 join 而不是 同态,因为虽然 fmap join . join == join. joinfmap join == join.[=20 不是真的=]