我想知道为什么这段代码不进行类型检查:
{-# LANGUAGE ScopedTypeVariables, Rank2Types, RankNTypes #-}
{-# OPTIONS -fglasgow-exts #-}
module Main where
foo :: [forall a. a]
foo = [1]
ghc 提示:
Could not deduce (Num a) from the context ()
arising from the literal `1' at exist5.hs:7:7
鉴于:
Prelude> :t 1
1 :: (Num t) => t
Prelude>
似乎 (Num t) 上下文无法匹配 arg 的 () 上下文。我无法理解的一点是,由于 () 比 (Num t) 更通用,因此后者应该包含前者。这与缺乏 Haskell 对子类型的支持有关吗?
感谢您对此发表任何评论。
最佳答案
你在这里没有使用存在量化。您正在使用等级 N 类型。
这里[forall a. a]
意味着每个元素必须具有所有可能的类型(不是任何,每个)。所以[undefined, undefined]
将是该类型的有效列表,基本上就是这样。
稍微扩展一下:如果列表的类型为 [forall a. a]
这意味着所有元素的类型都是 forall a. a
.这意味着任何接受任何类型参数的函数都可以将该列表的一个元素作为参数。如果你放入一个比 forall a. a
更具体的类型的元素,这将不再正确。 ,所以你不能。
要获得可以包含任何类型的列表,您需要使用存在量化定义自己的列表类型。像这样:
data MyList = Nil | forall a. Cons a MyList
foo :: MyList
foo = Cons 1 Nil
当然,除非您限制元素类型至少实例化
Show
,你不能对那种类型的列表做任何事情。
关于haskell - Haskell 中存在量化值的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3149975/