据我所知,仿函数是两个类别之间的映射,例如C http://mathurl.com/32qch9w.png中的对象到D http://mathurl.com/36b8r37.png中C http://mathurl.com/32qch9w.png和D http://mathurl.com/36b8r37.png所在的对象类别。
在Haskell中有 Hask ,其中对象是Haskell类型,而态射是Haskell函数。但是,Functor
类型类有一个函数fmap
,它在这些类型之间进行映射(因此它们是对象而不是类别本身):
fmap :: (a -> b) -> f a -> f b
f a
和f b
都是 Hask 中的对象。这是否意味着Haskell中Functor
的每个实例都是一个endofunctor,如果不是,Functor
真的代表一个函子?
我在这里缺少什么?类型也是Haskell中的类别吗?
答案 0 :(得分:26)
Functor
的实例指定两件事:类F
的类型构造函数* -> *
,即从Hask的对象到Hask的对象的映射,以及类型的函数(a -> b) -> (F a -> F b)
,即从Hask的箭头到Hask的箭头的映射,与对象映射F
兼容。所以,是的,Functor
的所有实例都是endofunctors。 Hackage上有几种可用的概括,例如: Control.Categorical.Functor
答案 1 :(得分:18)
是的,所有Functor
个实例都是 Hask 上的endofunctors - 事实上,来自所有 Hask 的endofunctors到一个正确的子类别,其对象是获得的类型通过应用特定类型的构造函数。该类型构造函数是与Functor
实例关联的,并提供对象的映射;态射的映射是fmap
,因为我们只关注笛卡尔闭合范畴的内部导数,它本身就是 Hask 中的态射系列。
考虑除Functor
个实例之外的其他仿函数,例如contravariant functors(从 Hask 到其相反的类别),确实有意义。 the Arrow
class中的arr
函数也对应于一个仿函数,从所有 Hask 到对象与 Hask 的对象相同的类别其态射由Arrow
实例与之关联的类型构造函数描述。
进一步的概括也是可能的(正如Daniel Wagner所指出的那样),但使用起来往往变得越来越尴尬。
答案 2 :(得分:4)
关于这一点的一个重要观点是,你真正想要的是 Hask 中的函子丰富,而不仅仅是普通的旧仿函数。 Hask 是笛卡尔式闭合的(not really,但它很难成为那样),因此它本身就很丰富了。
现在,丰富的endofunctors为您提供了一种限制语言中可实现的的方法:一个丰富的函子 Hask - > Hask 是对象(类型)f a
级别的函数,对于每对对象a, b
, Hask 中的态射 f:< strong> Hask (a,b) - &gt;的 Hask 强>(FA,FB)。当然,这只是fmap :: (a -> b) -> f a -> f b