【发布时间】:2026-02-14 14:55:02
【问题描述】:
假设我有两个以下类型的 Haskell 函数,并激活了 ExplicitForAll,
f :: forall a. (a -> Int)
g :: forall a. (Int -> a)
在我看来g 的类型与Int -> (forall a. a) 同构,因为例如g(2) 的类型是forall a. a。
但是,f 的类型看起来与 (forall a. a) -> Int 不同。 f 是一个多态函数,它知道在每个输入类型上计算什么 a,在数学上我猜它宁愿是一个函数族;但我认为它不能处理具有所有类型的单个参数。
类型量词分布在函数目标类型而不是函数源类型上是类型化 lambda 演算的规则吗?
Haskell 中是否存在 (forall a. a) -> Int 类型,可能被限制为类型类 (forall a. SomeClass a => a) -> Int ?有用吗?
【问题讨论】:
-
不,它们不是同构的。是什么让你这么认为?
-
如果你碰巧熟悉范畴论,
f :: forall a. F a -> G a可以看成是在a上自然 的函数族:这是自然变换@ 987654334@(假设F,G是函子,如本例所示)。 -
@n.m.
g(2) :: forall a. a不是一个充分的理由吗? -
@chi 的确,我的问题源于自然变换,这就是我谈到函数族的原因。你知道当
F或G是一个常量函子时,类型化的 lambda 演算是否有分配类型量词的规则? -
类型量词可以与逻辑中的箭头交换:命题
p -> forall a. q(a)等价于forall a. p -> q(a),前提是p不依赖于a。如果 Haskell 有存在类型,我们就会有同构(forall a. p(a) -> q) ~ ((exists a. p(a)) -> q)。它也与产品通勤(forall a. p a, forall a. q a) ~ forall a. (p a, q a)。总和比较棘手。