为什么`[1, "a"] :: [forall a.显示 a => a]` 不允许?
Why is `[1, "a"] :: [forall a. Show a => a]` not allowed?
以我(可能不正确)的理解,以下两个列表应该是等价的:
[1, "a"] :: [forall a. Show a => a]
data V = forall a. Show a => V a
[V 1, V "a"] :: [V]
然而,第一个不被接受,但第二个工作正常(ExistentialQuantification
)。
如果第一个列表不存在,那么map V :: ??? -> [V]
空格中的类型是什么?什么类型的机制强制包装器的存在?
你的理解不对。问题的很大一部分是您使用的传统存在量化语法对于任何不完全熟悉它的人来说都非常混乱。因此,我强烈建议您改用 GADT 语法,这也具有更强大的好处。最简单的事情就是启用 {-# LANGUAGE GADTs #-}
。当我们这样做的时候,让我们打开 {-# LANGUAGE ScopedTypeVariables #-}
,因为我讨厌想知道 forall
在任何特定位置意味着什么。您的 V
定义与
的定义完全相同
data V where
V :: forall a . Show a => a -> V
如果愿意,我们实际上可以删除显式 forall
:
data V where
V :: Show a => a -> V
所以 V
数据构造函数是一个函数,它接受 any 可显示类型的内容并生成 V
类型的内容。 map
的类型非常严格:
map :: (a -> b) -> [a] -> [b]
传递给 map
的列表的所有元素必须具有相同的类型。所以 map V
的类型就是
map V :: Show a => [a] -> [V]
现在让我们回到您的第一个表达式:
[1, "a"] :: [forall a. Show a => a]
现在这实际上是说 [1, "a"]
是一个列表,其中每个元素的类型都是 forall a . Show a => a
。也就是说,如果我提供任何作为 Show
实例的 a
,列表中的每个元素都应该具有该类型。这是不正确的。例如,"a"
没有类型 Bool
。这里还有另一个问题;类型 [forall a . Show a => a]
是 "impredicative"。我不明白这意味着什么的细节,但笼统地说,你在 ->
以外的类型构造函数的参数中插入了 forall
,这是不允许的。 GHC 可能会建议您启用 ImpredicativeTypes
扩展,但这确实行不通,所以您不应该这样做。如果你想要一个存在量化的列表,你需要先将它们包装在存在数据类型中或使用专门的存在列表类型。如果你想要一个普遍量化的东西的列表,你需要先把它们包起来(可能是在新类型中)。
以我(可能不正确)的理解,以下两个列表应该是等价的:
[1, "a"] :: [forall a. Show a => a]
data V = forall a. Show a => V a
[V 1, V "a"] :: [V]
然而,第一个不被接受,但第二个工作正常(ExistentialQuantification
)。
如果第一个列表不存在,那么map V :: ??? -> [V]
空格中的类型是什么?什么类型的机制强制包装器的存在?
你的理解不对。问题的很大一部分是您使用的传统存在量化语法对于任何不完全熟悉它的人来说都非常混乱。因此,我强烈建议您改用 GADT 语法,这也具有更强大的好处。最简单的事情就是启用 {-# LANGUAGE GADTs #-}
。当我们这样做的时候,让我们打开 {-# LANGUAGE ScopedTypeVariables #-}
,因为我讨厌想知道 forall
在任何特定位置意味着什么。您的 V
定义与
data V where
V :: forall a . Show a => a -> V
如果愿意,我们实际上可以删除显式 forall
:
data V where
V :: Show a => a -> V
所以 V
数据构造函数是一个函数,它接受 any 可显示类型的内容并生成 V
类型的内容。 map
的类型非常严格:
map :: (a -> b) -> [a] -> [b]
传递给 map
的列表的所有元素必须具有相同的类型。所以 map V
的类型就是
map V :: Show a => [a] -> [V]
现在让我们回到您的第一个表达式:
[1, "a"] :: [forall a. Show a => a]
现在这实际上是说 [1, "a"]
是一个列表,其中每个元素的类型都是 forall a . Show a => a
。也就是说,如果我提供任何作为 Show
实例的 a
,列表中的每个元素都应该具有该类型。这是不正确的。例如,"a"
没有类型 Bool
。这里还有另一个问题;类型 [forall a . Show a => a]
是 "impredicative"。我不明白这意味着什么的细节,但笼统地说,你在 ->
以外的类型构造函数的参数中插入了 forall
,这是不允许的。 GHC 可能会建议您启用 ImpredicativeTypes
扩展,但这确实行不通,所以您不应该这样做。如果你想要一个存在量化的列表,你需要先将它们包装在存在数据类型中或使用专门的存在列表类型。如果你想要一个普遍量化的东西的列表,你需要先把它们包起来(可能是在新类型中)。