我的范畴论一点都不强(我是从 Haskell 的编程方面开始的,最近一直在尝试学习它的一些概念的范畴论基础)。但这是我所拥有的:
在 Haskell 中,函子是类型构造函数,这意味着它从一般类型映射到“函子中的类型”。
在范畴论中,函子从一个范畴的对象映射到另一范畴的对象。
在将类别理论应用于 Haskell 时,我们假设我们正在使用类别 Hask,即 Haskell 类型的类别。
所以 Haskell 函子不是一般范畴论的函子;它们都从 Hask 映射到 Hask 的子类别(因为某些函子 f 的类型 f a 和任意类型 a 仍然是 Haskell 类型)。例如,Maybe 函子将 Hask 中的对象(类型)映射到 Maybe a 形式的类型类别。
函数在 Haskell 中是一等的,所以函数类型是完全普通的类型(并且是 Hask 的对象),所以仿函数也将函数类型映射到“函数类型在函子”。因此,短语“函子内的函数”是一种类型中 value 的简写,该类型是通过将函子应用于函数类型而产生的。例如Just (+1) 是Maybe (Int -> Int) 类型中的一个特定值,它是Maybe 函子将对象Int -> Int 映射到的对象(类型)。
因此,“应用函子”是具有一些额外规则的函子,这些规则足以获取 值,这些值是函子“目标”类别的对象类型中的函数,并应用那些值到目标类别中类型中的其他值。
再次以Maybe 为例,如果我们只知道它是一个函子,它为我们提供了对象Int -> Char 和Maybe (Int -> Char) 之间以及对象Int 和Maybe Int 之间以及对象之间的对应关系对象Char 和Maybe Char。但是虽然我们有能力在Int -> Char 和Int 中获取一个值并在Char 中产生一个值,但Maybe 作为一个函子并不能保证我们有能力进行一些相应的操作具有Maybe (Int -> Char) 中的值和Maybe Int 中的值。
当我们也知道它是一个应用函子时,我们确实有能力在Maybe (Int -> Char) 中获取一个值,在Maybe Int 中获取一个值并在Maybe Char 中生成一个值,这满足应用程序的某些属性将Int -> Char 值转换为Int 值。
据我所知,从纯范畴论的角度来看,应用函子并不是很有趣。这可能是因为范畴论关注的是 objects 之间的关系,这对应于 Haskell 中的类型,但从编程的角度来看,应用函子是由这些类型中的 值 之间的关系驱动的? (我们希望使用仿函数获得的“函数类型”中的值仍然能够应用于事物进行计算)。