在理解Functor以前,必须对抽象代数的范畴论有所了解,有范畴论的知识做为铺垫,感受Functor也不是那么的难以理解了。编程
一个范畴C包括:函数
一个由对象所构成的类ob(C)
spa
对象之间的态射所构成的类hom(C)。每个态射f都会有一个“源对象”a和“目标对象”b,且a和b 都在ob(C)以内。所以写成f:a -> b,且称f为由a到b的态射。全部a到b的态射所构成的“态射类”, 其标记为hom(a,b)或者homC(a,b)。
orm
对三个对象a、b和c,二元运算hom(a,b) * hom(b,c) -> hom(a,c)称之为态射复合;f :a -> b 和g : b -> c 的复合写成g . f 或者gf。
对象
态射复合知足下列公理:接口
(结合律)若f:a -> b、g:b -> c且 h:c -> d,则 h.(g.f) = (h.g).f;it
(单位元)对任一对象x,存在一态射1x:x -> x,使得每一态射f:a -> b,都会有1b.f = f = f.1a。 此态射称为“x的单位态射”。 margin
千万别被这些概念吓到了,从编程者的角度考虑,范畴就是一种抽象,一种interface,理解一个抽象接口最好的方式就是看它的具体实现,而范畴最容易理解的一个具体就是Set,集合,咱们高中就接触过的东西。一个集合就是一个范畴,咱们看看它是怎么知足的:top
它的对象是集合的元素集合
它的态射就是集合之间的映射(函数)
它的态射复合就是映射的复合(函数的复合)
了解了范畴的概念,接下来咱们在看看函子,函子究竟是个什么东西呢?下面看它的定义:
设C和D为范畴,从C到D的函子为一个映射F:
将每一个对象X <- C 映射到一个对象 F(X) <- D 上,
将每一个态射f : X -> Y <- C 映射至一态射 F(f) : F(X) -> F(Y) <- D上
看函子的定义知道了函子的做用大概就是把一个范畴转换为另外一个范畴,因此函子是范畴间的一种映射。
若是咱们把函子在抽象一层的话,会发现函子也是遵循着范畴的定义,下面看看:
它的对象是函子(一个把一个范畴映射到另外一个范畴的东西)
它的态射是天然变换
它的态射复合就是天然变换之间的复合
因此咱们的函子也是知足范畴的定义,它自身也够成了一个范畴,叫作函子范畴。而后咱们还有一种特殊的函子,它是把一个范畴映射到自身,它叫自函子。