類別理論中的函式
Functor 在類別理論中被定義為類別之間的結構保持對映(同態)。具體而言,(所有)物件被對映到物件,並且(所有)箭頭被對映到箭頭,從而保留了類別定律。
物件是 Haskell 型別和態射的類別是 Haskell 函式,稱為 Hask 。因此,從 Hask 到 Hask 的仿函式將包括型別到型別的對映以及從函式到函式的對映。
這個類別理論概念與 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