首先,上下文中的“刚性”类型变量是指由该上下文外部的量词绑定的类型变量,因此无法与其他类型变量统一。
这非常像由lambda绑定的变量那样工作:给定lambda (\x -> ... )
,您可以从“外部”将其应用于您喜欢的任何值;但在内部,您不能简单地确定的值x
应为某个特定值。为x
lambda内部选择一个值听起来很愚蠢,但这就是“无法匹配等等,刚性类型变量,等等等等”的错误。
请注意,即使不使用显式forall
量词,任何顶级类型签名forall
对于所提及的每个类型变量都具有隐式含义。
当然,这不是您得到的错误。“转义类型变量”的含义甚至更愚蠢-就像拥有一个lambda(\x -> ...)
并尝试使用lambdax
之外的特定值,而与将其应用于参数无关。不,不将lambda应用于某些对象并使用结果值-我的意思是实际上在定义变量的范围之外使用变量本身。
类型可能发生这种情况的原因(似乎不像使用lambda的示例那样荒谬)是因为存在两个“类型变量”概念:与其他此类变量通过类型推断。另一方面,您具有上述量化的类型变量,这些变量专门标识为可能的类型。
考虑lambda表达式的类型(\x -> x)
。从一个完全不确定的类型开始a
,我们看到它需要一个参数并将其范围缩小到a -> b
,然后我们看到它必须返回与其参数相同类型的东西,因此我们将其进一步缩小到a -> a
。但是现在它适用于a
您可能需要的任何类型,因此我们给它一个数量词(forall a. a -> a)
。
因此,当您有一个由量词绑定的类型时,会发生转义的类型变量,GHC推断该变量应与该量词范围之外的未确定类型统一。
因此,显然我忘了在这里实际解释术语“ skolem类型变量”,嘿。正如评论中所提到的,在我们的例子中,它实际上是“刚性类型变量”的同义词,因此上面仍然解释了这个想法。
我不完全确定该术语的起源,但我想它涉及Skolem范式,并代表普遍性的存在性量化,就像在GHC中所做的那样。skolem(或刚性)类型变量是在某种范围内出于某种原因具有未知但特定的类型的变量-属于多态类型的一部分,来自存在数据类型&c。