Haskell 函子定律证明了结构的完全保持吗?

Haskell 函子定律证明了结构的完全保持吗?,haskell,functional-programming,category-theory,Haskell,Functional Programming,Category Theory,在文件中,以下两个是函子定律,所有函子都应该遵守 fmap id == id fmap (f . g) == fmap f . fmap g 我的直觉告诉我,函子应该工作的方式是,它们应该是“结构保持”,或者换句话说,如果你有一个函数f::a->b,它是反的g::b->a,那么 fmap f . fmap g == id 我还没能想出一个符合前两条法律并违反第二条法律的fmap实施方案,但这很难证明。有人能告诉我吗?事实上,你的“第三”函子定律直接来自于实际的函子定律和f。G≡

在文件中,以下两个是函子定律,所有函子都应该遵守

fmap id  ==  id
fmap (f . g)  ==  fmap f . fmap g
我的直觉告诉我,函子应该工作的方式是,它们应该是“结构保持”,或者换句话说,如果你有一个函数
f::a->b
,它是反的
g::b->a
,那么

fmap f . fmap g  ==  id
我还没能想出一个符合前两条法律并违反第二条法律的
fmap
实施方案,但这很难证明。有人能告诉我吗?

事实上,你的“第三”函子定律直接来自于实际的函子定律和
f。G≡ id

fmap f . fmap g ≡ fmap (f . g) ≡ fmap id ≡ id

还有更多:Haskell确保如果第一定律适用于
函子
实例,那么第二定律也适用(这是
fmap
类型的自由定理)。即,您只需证明
fmap id≡ id
为您的
函子
实例指定一条法则,以确保其有效。

f时。G≡ id
,函数
f
g
是否都有数学术语描述它们之间的关系?(我想我在什么地方读过关于同构的书,但我不确定。)@Sibi:为什么,是的,
f
g
的左逆,而
g
f
的右逆。这并不意味着这两个函数的域和辅域同构,例如
show::Int->String
read
作为左逆,尽管
Int
的基数明显小于
String
@Sibi注意
f。G≡ id
并不意味着
g。F≡ id
。然而,如果是这样,那么这两个函数都称为“同构”。否则,
f
称为“收回”(或“g的左反转”),
g
称为“部分”(或“f的右反转”)。我现在看到了,谢谢。我不知何故试图用另一种方式来解释,但我无法完全说服自己。我认为让我绊倒的主要原因是,我尝试过的函数,我认为它们彼此是相反的,但实际上并不是相反的。有一件事困扰着我这个直观的公式:没有逆的函数呢?当然
fmap(const“Foo”)
在某种意义上也是保持结构的吗?是的,但是你不能用
const“Foo”
来证明这个定律是正确的——你必须选择另一个函数。我并不是说函子只对法则所包含的函数类型有效。@duplode想象一棵树
数据树a=Leaf |节点a[tree a]
。当我们谈论树a的“结构”时,我们会想到每个节点有多少子树,以及这些子树是如何排列的。因此,您可能会说我们对
t
及其节点中的任何内容感兴趣。事实上,我们可以通过
fmap(const())t
@duplode捕捉到,函子定律定义了函子的结构保留属性,你不能从定律中证明它。我只想向未来的谷歌人指出,它确实很好地说服了我,结构是保留的,甚至比这更进一步!