【发布时间】:2012-05-31 22:58:00
【问题描述】:
Haskell Wiki 很好地解释了如何使用存在类型,但我不太了解它们背后的理论。
考虑这个存在类型的例子:
data S = forall a. Show a => S a -- (1)
为我们可以转换为String的东西定义一个类型包装器。 wiki 提到我们真正想要定义的类型是
data S = S (exists a. Show a => a) -- (2)
即一个真正的“存在”类型 - 我大致认为这是在说“数据构造函数S 采用Show 实例存在 的任何类型并包装它”。实际上,您可能可以编写如下 GADT:
data S where -- (3)
S :: Show a => a -> S
我没有尝试编译它,但它似乎应该可以工作。对我来说,GADT 显然等同于我们想要编写的代码 (2)。
但是,我完全不明白为什么 (1) 等同于 (2)。为什么将数据构造函数移到外部会将forall 变成exists?
我能想到的最接近的事情是逻辑上的De Morgan's Laws,其中交换否定和量词的顺序将存在量词变成全称量词,反之亦然:
¬(∀x. px) ⇔ ∃x. ¬(px)
但数据构造函数似乎与否定运算符完全不同。
使用forall 而不是不存在的exists 定义存在类型的能力背后的理论是什么?
【问题讨论】:
标签: haskell types type-systems existential-type quantifiers