alx*_*x9r 7 haskell terminology functor category-theory
从类别理论的角度来看,这个答案包括以下声明:
......事实是,co和逆变函数之间没有真正的区别,因为每个函子只是一个协变函子.
...
更详细地说,从类别C到类别D的逆变函数F只不过是F类型的(协变)函子:C op →D,从C的相反类别到类别D.
在另一方面,Haskell的Functor和Contravariant仅仅需要fmap和contramap,分别为实例来定义.这表明,从Haskell的角度来看,存在Contravariant但不是Functors的对象(反之亦然).
因此,似乎在类别理论中"co和逆变函子之间没有真正的区别",而在Haskell中,Contravariant和之间有区别Functor.
我怀疑这种差异与Haskell在Hask中发生的所有实现有关,但我不确定.
我认为我自己理解每个类别理论和Haskell的观点,但我很难找到连接两者的直觉.
Dan*_*ner 10
这是为了方便.
可以使用更通用的Functor类,并在Hask(对应于我们现有的Functor)和从Hask ^ op到Hask(对应于我们现有的Contravariant)的仿函数中定义endofunctors的实例.但这需要一个具象的认知成本和一个相当文字的语法成本:然后必须依靠类型推断或类型注释来选择一个实例,并且有明确的转换(命名Op和getOp在标准库中)进出Hask ^ op .
使用名称fmap并contramap放宽两种成本:读者不需要在他们的头脑中运行Hindley-Milner来决定在明确时选择哪个实例,并且编写者不需要提供显式转换或输入注释来选择案例中的实例它不明确的地方.
(我实际上在这里重写了一点历史.真正的原因是因为语言设计师认为专业Functor是有用的,没有想象或没有看到更普遍的需要Functor.人们后来出现并注意到它会有时候是有用的.但是对于广义Functor类的经验表明这可能是单调乏味的,并且最常见的案例的专门课程毕竟是出乎意料的好,因为上述原因.)
在数学上,考虑逆变函子作为一个独特的类函子的只是一个符号上的方便; 逆变仿函数F : C -> D总是被定义为协变仿函数F' : C^{op} -> D,因此摆脱逆变仿函数的想法只会迫使你明确地谈论相反的类别.
在Haskell中,Functor该类表示(假设)类别Hask上的endofunctor.没有方便的方法直接表示HASK OP(或者至少,不是以帮助我们定义该类别的仿函数的形式),也没有定义exofunctor*的类型类,所以我们定义了Contrafunctor其contramap函数可以反转的类来自Hask的箭头"按需",可以这么说.
*"exofunctor"是一个真正的术语吗?我只是说明了一个不是endofunctor的仿函数.
想象一下,我们有类似以下的东西.
class MoreAccurateFunctor c d f where
fmap :: c a b -> d (f a) (f b)
Run Code Online (Sandbox Code Playgroud)
既然(->)是Category(这是Hask)的一个实例,我们会有Functor ~ MoreAccurateFunctor (->) (->).
现在,想象一下,我们有Dual (->)双重类别(->)(这将是Hask Op,我们会有Dual (->) a b ~ (b -> a)),我们会有Contravariant ~ MoreAccurateFunctor (Dual (->)) (->).
我不知道这是否有帮助但是这个想法是指出这个事实,Functor并且Contravariant是两个专业化,MoreAccurateFunctor而后一个类更接近类别理论中的仿函数的定义.