类别理论作为组织抽象的系统

范畴理论是一种现代数学理论,是抽象代数的一个分支,侧重于连通性和关系的本质。它为许多高度可重用的编程抽象提供坚实的基础和通用语言非常有用。Haskell 使用类别理论作为标准库和几个流行的第三方库中可用的一些核心类型类的灵感。

一个例子

Functor 类型类说如果 F 类型实例化 Functor(我们为其写了 Functor F)那么我们有一个泛型操作

fmap :: (a -> b) -> (F a -> F b)

这让我们映射F。标准(但不完美)的直觉是 F a 是一个充满 a 类型值的容器,fmap 允许我们对每个包含的元素应用转换。一个例子是 Maybe

instance Functor Maybe where
  fmap f Nothing = Nothing     -- if there are no values contained, do nothing
  fmap f (Just a) = Just (f a) -- else, apply our transformation

鉴于这种直觉,一个常见的问题是“为什么不把 Functor 称为像 Mappable 这样明显的东西?”。

一种类别理论的暗示

原因是 Functor 适用于类别理论中的一组共同结构,因此通过调用 Functor``Functor,我们可以看到它如何连接到这个更深层次的知识体系。

特别是,类别理论高度关注箭头从一个地方到另一个地方的想法。在 Haskell 中,最重要的一组箭头是功能箭头 a -> b。在类别理论中研究的一个常见问题是一组箭头如何与另一组相关联。特别是,对于任何类型的构造函数 F,形状 F a -> F b 的箭头组也很有趣。

因此,一个 Functor 是任何 F,正常的 Haskell 箭头 a -> bF 特定的箭头 F a -> F b 之间存在联系。连接由 fmap 定义,我们也认识到必须遵守的一些准则

forall (x::F a) . fmap id x == x

forall (f::a -> b) (g::b -> c) . fmap g . fmap f = fmap (g . f)

所有这些定律都源于对 Functor 的类别理论解释,如果我们只认为 Functor映射元素有关,那么这些定律就不那么明显了。