[英]What is the difference between forall a. [a] and [forall 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]
的空白中的类型是什么map V :: ??? -> [V]
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
数据构造函数是一个函数,它接受任何可显示类型的东西并产生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
forall a . Show a => a
。 也就是说,如果我提供任何a
Show
实例,则列表中的每个元素都应该具有该类型。 这是不正确的。 例如, "a"
没有类型Bool
。 这里还有一个问题; 类型[forall a . Show a => a]
[forall a . Show a => a]
是“不可预测的”。 我不明白这意味着什么的细节,但松散地说,你在->
以外的类型构造函数的参数中坚持了forall
,这是不允许的。 GHC 可能会建议您启用ImpredicativeTypes
扩展,但这确实不起作用,因此您不应该这样做。 如果你想要一个存在量化事物的列表,你需要首先将它们包装在存在数据类型中,或者使用专门的存在列表类型。 如果你想要一个普遍量化的东西的列表,你需要先把它们包装起来(可能是新的)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.