类别理论中的函数

Functor 在类别理论中被定义为类别之间的结构保持映射(同态)。具体而言,(所有)对象被映射到对象,并且(所有)箭头被映射到箭头,从而保留了类别定律。

对象是 Haskell 类型和态射的类别是 Haskell 函数,称为 Hask 。因此,从 HaskHask 的仿函数将包括类型到类型的映射以及从函数到函数的映射。

这个类别理论概念与 Haskell 编程构造 Functor 的关系是相当直接的。从类型到类型的映射采用 f :: * -> *类型的形式,从函数到函数的映射采用函数 fmap :: (a -> b) -> (f a -> f b) 的形式。把它们放在一起,

class Functor (f :: * -> *) where
    fmap :: (a -> b) -> f a -> f b

fmap 是一个操作,它接受一个函数(一种态射),:: a -> b,并将它映射到另一个函数:: f a -> f b。假设(但是程序员要确保)Functor 的实例确实是数学仿函数,保留了 Hask 的分类结构:

fmap (id {- :: a -> a -})  ==  id {- :: f a -> f a -}
fmap (h . g)               ==  fmap h . fmap g

fmap 升降机函数:: a -> b 成的一个子类别 Hask 以保留任何身份箭头两者的存在,和组合物的相关性的方法。

Functor 类只对 Hask 上的 endo 仿函数进行编码。但在数学中,仿函数可以在任意类别之间进行映射。对这个概念的更忠实的编码看起来像这样:

class Category c where
    id  :: c i i
    (.) :: c j k -> c i j -> c i k

class (Category c1, Category c2) => CFunctor c1 c2 f where
    cfmap::c1 a b -> c2 (f a) (f b)

标准的 Functor 类是此类的一个特例,其中源类和目标类都是 Hask 。例如,

instance Category (->) where        -- Hask
    id    = \x -> x
    f . g = \x -> f (g x)

instance CFunctor (->) (->) [] where
    cfmap = fmap