首页 > 解决方案 > 为什么 Haskell 中的 co 和逆变函子有区别,但范畴论没有区别?

问题描述

从范畴论的角度来看,这个答案包括以下陈述:

...事实是 co 和逆变函子之间没有真正的区别,因为每个函子都只是一个协变函子。

...

更详细地说,从 C 类到 D 类的逆变函子 F 只不过是 F 类型的(协变)函子:C op →D,从 C 的相反类别到 D 类。

另一方面,Haskell 的FunctorContravariant仅要求fmapcontramap分别为实例定义。这表明,从 Haskell 的角度来看,存在对象是Contravariant但不是Functors(反之亦然)。

Contravariant因此,似乎在范畴论中“co 和逆变函子之间没有真正的区别”,而在 Haskell 中,和之间有区别Functor

我怀疑这种差异与 Haskell 中发生在 Hask 中的所有实现有关,但我不确定。

我想我自己理解类别理论和 Haskell 的每一个观点,但我正在努力寻找一种将两者联系起来的直觉。

标签: haskellterminologyfunctorcategory-theory

解决方案


是为了方便。

可以使用更通用Functor的类,并为 Hask 上的 endofunctors(对应于我们现有的Functor)和从 Hask^op 到 Hask 的函子(对应于我们现有的 )定义实例Contravariant。但这带来了象征性的认知成本和相当字面的句法成本:然后必须依靠类型推断或类型注释来选择实例,并且有显式转换(在标准库中命名OpgetOp进出 Hask^op .

使用名称fmapcontramap放宽这两种成本:读者不需要在头脑中运行 Hindley-Milner 来决定选择哪个实例,当它是明确的时,作者不需要给出明确的转换或类型注释来选择一个实例以防万一模棱两可的地方。

(实际上我在这里稍微改写了历史。真正的原因是因为语言设计者认为专业化Functor会很有用,并且没有想象或没有看到需要更通用的Functor. 人们后来发现它会有时是有用的。但是使用泛化Functor类的经验表明这可能很乏味,而且由于上述原因,最常见的情况下的专门化类最终证明是非常合适的。)


推荐阅读