類別理論中的函式

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