简体   繁体   English

GHC / GHCi意外接受的代码

[英]Code unexpectedly accepted by GHC/GHCi

I don't understand why this code should pass type-checking: 我不明白为什么这段代码应该通过类型检查:

foo :: (Maybe a, Maybe b)
foo = let x = Nothing in (x,x)

Since each component is bound to the same variable x , I would expect that the most general type for this expression to be (Maybe a, Maybe a) . 由于每个组件都绑定到相同的变量x ,所以我希望此表达式的最通用类型是(Maybe a, Maybe a) I get the same results if I use a where instead of a let . 如果使用where而不是let我将得到相同的结果。 Am I missing something? 我想念什么吗?

Briefly put, the type of x gets generalized by let . 简而言之, x的类型由let推广。 This is a key step in the Hindley-Milner type inference algorithm. 这是Hindley-Milner类型推断算法中的关键步骤。

Concretely, let x = Nothing initially assigns x the type Maybe t , where t is a fresh type variable. 具体来说, let x = Nothing最初为x分配类型Maybe t ,其中t是新鲜的类型变量。 Then, the type gets generalized, universally quantifying all its type variables (technically: except those in use elsewhere, but here we only have t ). 然后,对类型进行泛化,通用地量化其所有类型变量(技术上:除了在其他地方使用的变量,但这里我们只有t )。 This causes x :: forall t. Maybe t 这导致x :: forall t. Maybe t x :: forall t. Maybe t . x :: forall t. Maybe t Note that this is exactly the same type as Nothing :: forall t. Maybe t 请注意,此类型与Nothing :: forall t. Maybe t完全相同Nothing :: forall t. Maybe t Nothing :: forall t. Maybe t . Nothing :: forall t. Maybe t

Hence, each time we use x in our code, that refers to a potentially different type Maybe t , much like Nothing . 因此,每次我们在代码中使用x时,它都表示可能不同的类型Maybe t ,就像Nothing一样。 Using (x, x) gets the same type as (Nothing, Nothing) for this reason. 因此,使用(x, x)(Nothing, Nothing)类型相同。

Instead, lambdas do not feature the same generalization step. 相反,lambda 具有相同的概括步骤。 By comparison (\\x -> (x, x)) Nothing "only" has type forall t. (Maybe t, Maybe t) 相比之下(\\x -> (x, x)) Nothing “ only”的类型为forall t. (Maybe t, Maybe t) forall t. (Maybe t, Maybe t) , where both components are forced to be of the same type. forall t. (Maybe t, Maybe t) ,其中两个组件都被强制为相同类型。 Here x is again assigned type Maybe t , with t fresh, but it is not generalized. 在这里x再次被赋予类型Maybe t ,其中t fresh,但是没有被概括。 Then (x, x) is assigned type (Maybe t, Maybe t) . 然后(x, x)被分配类型(Maybe t, Maybe t) Only at the top-level we generalize adding forall t , but at that point is too late to obtain a heterogeneous pair. 仅在最高级别上,我们才一般性地加上了forall t ,但是在这一点上太晚了,无法获得异构对。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM