23

据我了解,仿函数是两个类别之间的映射,例如从对象 inCDwhereCDare 类别的对象。

在 Haskell 中有Hask,其中对象是 Haskell 类型,而态射是 Haskell 函数。但是,Functor类型类有一个函数fmap在这些类型之间进行映射(因此它们是对象而不是类别本身):

fmap :: (a -> b) -> f a -> f b

f a并且f b都是Hask中的对象。这是否意味着 Haskell 中的每个实例Functor都是一个内函子,如果不是Functor真的代表一个函子?

我在这里想念什么?Haskell中的类型也是类别吗?

4

3 回答 3

27

的实例Functor指定了两件事:Fkind的类型构造函数* -> *,即从 Hask 的对象到 Hask 的对象的映射,以及 type 的函数(a -> b) -> (F a -> F b),即从 Hask 的箭头到与对象兼容的 Hask 的箭头的映射-映射F。所以,是的,所有的实例Functor都是内函子。在 Hackage 上有几个可用的概括,例如Control.Categorical.Functor

于 2013-02-11T20:26:03.743 回答
19

是的,所有Functor实例都是 Hask 上的endofunctors——事实上,所有 Hask 的endofunctor到一个适当的子类别,其对象是通过应用特定类型构造函数获得的类型。该类型构造函数是Functor实例关联的对象,并提供对象的映射;态射的映射是fmap,它(因为我们只关心笛卡尔闭范畴上的内函子)本身就是Hask中的一个态射族。

除了可以有实例的函子之外,考虑其他函子确实是有意义的Functor,例如逆变函子(从Hask到其相反的类别)。arr函数也对应一个函子,从Hask的所有对象到其对象与Hask相同的类,其态射由实例关联的类型构造函数描述。ArrowArrow

进一步的概括也是可能的(正如 Daniel Wagner 所指出的),但使用起来往往变得越来越尴尬。

于 2013-02-11T20:31:36.763 回答
4

关于这一点的重要一点是,您真正想要的是在Hask中丰富的函子,而不仅仅是普通的旧函子。Hask是笛卡尔封闭的(不是真的,但它努力成为一个封闭的),因此它本身自然丰富。

现在,丰富的 endofunctor 为您提供了一种限制语言内可实现的方法:丰富的仿函数Hask -> Hask是对象(类型)级别的函数,f a并且对于每对对象, Haska, b的态射f : Hask ( a,b) ->哈斯克(fa,fb)。当然,这只是fmap :: (a -> b) -> f a -> f b

于 2013-02-13T10:45:06.473 回答