根据GHC文件,给出以下声明:
data Foo = forall a. MkFoo a (a -> Bool)
| Nil
Run Code Online (Sandbox Code Playgroud)
然后
MkFoo :: forall a. a -> (a -> Bool) -> Foo
Run Code Online (Sandbox Code Playgroud)
(几乎)与以下伪Haskell声明同构
MkFoo :: (exists a . (a, a -> Bool)) -> Foo
Run Code Online (Sandbox Code Playgroud)
因此,不需要分离的"存在"关键字.因为:
Haskell程序员可以安全地考虑上面给出的普通的通用量化类型.
但我不确定这意味着什么.有人可以解释一下,为什么我们可以使用通用量词来表达存在量化?
chi*_*chi 12
在逻辑(经典或直觉)中,公式
(exists x. p x) -> q
forall x. (p x -> q)
Run Code Online (Sandbox Code Playgroud)
是等价的(注意,q不依赖于x上述).这可以用来表达存在主义量化的普遍量化,前提是存在主义在左侧隐含着意义.(这是一个经典的证据.)
在函数式编程中,您可以实现相同的功能.而不是写作
-- Pseudo-Haskell follows
f :: (exists a. (a, a->Int)) -> Int
f (x,h) = h x
Run Code Online (Sandbox Code Playgroud)
我们可以用
-- Actual Haskell
f :: forall a. (a, a->Int) -> Int
f (x,h) = h x
Run Code Online (Sandbox Code Playgroud)
所以我们可以做到没有存在量化,至少在如上所述的情况下.
当它不在箭头的左侧时,仍然需要存在量化.例如,
g :: exists a. (a, a->Int)
g = (2 :: Int, \x -> x+3)
Run Code Online (Sandbox Code Playgroud)
唉,Haskell选择不包括这些类型.可能,这种选择是为了使已经复杂的类型系统变得过于复杂.
但是,Haskell得到了存在的数据类型,它只需要在存在主体周围包装/解包一个构造函数.例如,使用GADT语法,我们可以写:
data Ex where
E :: forall a. (a, a->Int) -> Ex
g :: Ex
g = E (2 :: Int, \x -> x+3)
Run Code Online (Sandbox Code Playgroud)
最后,让我补充一点,存在性也可以通过rank-2类型和continuation-passing来模拟:
g :: forall r. (forall a. (a, a->Int) -> r) -> r
g k = k (2 :: Int, \x -> x+3)
Run Code Online (Sandbox Code Playgroud)