【发布时间】:2021-04-21 05:43:28
【问题描述】:
我知道 Haskell 中的许多名称都受到范畴论术语的启发,我正试图准确理解类比的开始和结束位置。
分类Hask
我已经知道 Hask is not (necessarily) a category 是因为一些关于严格/懒惰和 seq 的技术细节,但现在让我们把它放在一边。为了清楚起见,
-
Hask的对象是具体类型,即类型为*。这包括像Int -> [Char]这样的函数类型,但不包括像Maybe :: * -> *这样需要类型参数的任何东西。但是,具体类型Maybe Int :: *属于Hask。类型构造函数/多态函数更像是自然变换(或从Hask到自身的其他更一般的映射),而不是态射。 -
Hask的态射是 Haskell 函数。对于A和B这两种具体类型,hom 集Hom(A,B)是签名为A -> B的函数集。 - 函数组合由
f . g给出。如果我们担心严格性,我们可能会 redefine composition 严格或小心 defining equivalence classes 的函数。
Functors 是 Hask 中的 Endofunctors
我认为上面的技术细节与我在下面的困惑没有任何关系。我想我理解这意味着说every instance of Functor is an endofunctor in the category Hask。也就是说,如果我们有
class Functor (F :: * -> *) where
fmap :: (a -> b) -> F a -> F b
-- Maybe sends type T to (Maybe T)
data Maybe a = Nothing | Just a
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
Functor 实例Maybe 对应于从Hask 到Hask 的函子,方式如下:
-
对于
Hask中的每个具体类型a,我们分配具体类型Maybe a -
对于
Hask中的每个态射f :: A -> B,我们分配发送Nothing ↦ Nothing和Just x ↦ Just (f x)的态射Maybe A -> Maybe B。
常数(endo)函子
类别 C 上的 constant (endo)functor 是一个函子 Δc : C → C,将类别 C 的每个对象映射到固定对象 c∈C,并将 C 的每个态射映射到固定对象的恒等态射 id_c : c → c。
ConstFunctor
考虑Data.Functor.Const。为了清楚起见,我在这里重新定义,区分类型构造函数Konst :: * -> * -> *和数据构造函数Const :: forall a,b. a -> Konst a b。
newtype Konst a b = Const { getConst :: a }
instance Functor (Konst m) where
fmap :: (a -> b) -> Konst m a -> Konst m b
fmap _ (Const v) = Const v
这个类型检查是因为数据构造函数Const是多态的:
v :: a
(Const v) :: forall b. Konst a b
我可以认为Konst m 是Hask 类别中的内函子,因为在fmap 的实现中,
- 在左侧,
Const v显示为Konst m a,由于多态性,这没关系 - 在右侧,
Const v显示为Konst m b,由于多态性,这是可以的
但如果我们试图将 Konst m :: * -> * 视为范畴论意义上的常数函子,我的理解就会崩溃。
-
什么是固定对象?类型构造函数
Konst m接受一些具体类型a并为我们提供Konst m a,至少从表面上看,它是每个a的不同具体类型。我们真的很想将每个类型a映射到固定类型m。 -
根据类型签名,
fmap接受一个f :: a -> b并给我们一个Konst m a -> Konst m b。如果Konst m类似于常量函子,则fmap需要将每个态射发送到固定类型m上的恒等态射id :: m -> m。
问题
所以,这是我的问题:
-
Haskell 的
Const函子在哪些方面类似于范畴论中的常数函子(如果有的话)? -
如果这两个概念不等价,是否甚至可以在 Haskell 代码中表达范畴论常数函子(比如说,称之为
SimpleConst)?我快速尝试了一下,遇到了与上述幻象类型的多态性相同的问题:
data SimpleKonst a = SimpleConst Int
instance Functor SimpleConst where
fmap :: (a -> b) -> SimpleConst a -> SimpleConst b
fmap _ (SimpleConst x) = (SimpleConst x)
-
如果#2 的答案是肯定的,如果是,那么在范畴论意义上,这两个 Haskell 函数有什么关系?也就是说,
SimpleConst对应于 Haskell 中的Const,就像常量函子对应于范畴论中的__?__? -
幻象类型是否会给将
Hask视为一个类别造成问题?我们是否需要修改Hask的定义,使对象真正成为类型的等价类,如果没有幻像类型参数,这些类型本来是相同的?
编辑:自然同构?
看起来多态函数getConst :: forall a,b. Konst a b -> a是从函子Konst m到常数函子Δm : Hask → Hask的自然同构η : (Konst m) ⇒ Δm的候选者,尽管我还不能确定后者是否可以用 Haskell 代码表达。
自然变换法则是η_x = (Konst m f) . η_y。我无法证明这一点,因为我不知道如何正式推理 (Const v) 从类型 Konst m a 到 Konst m b 的转换,除了挥手说“存在双射!”。
相关参考资料
以下是上面尚未链接的可能相关问题/参考的列表:
【问题讨论】:
-
忘记常量。 Haskell 恒等式函子也不是分类恒等式。没关系,因为
Id a和a是同构的,具有明显的双射。现在你能在Konst a x和a之间找到一个吗?
标签: haskell functor category-theory phantom-types