Haskell 理解Hindley-Milner型推理中的多型
我正在读维基百科的一篇文章,试图从中找到一些意义。到目前为止,我的理解是:Haskell 理解Hindley-Milner型推理中的多型,haskell,type-inference,type-systems,lambda-calculus,hindley-milner,Haskell,Type Inference,Type Systems,Lambda Calculus,Hindley Milner,我正在读维基百科的一篇文章,试图从中找到一些意义。到目前为止,我的理解是: 类型分为单型或多型 单类型进一步分类为类型常量(如int或string)或类型变量(如α和β) 类型常量可以是具体类型(如int和string)或类型构造函数(如Map和Set) 类型变量(如α和β)充当具体类型的占位符(如int和字符串) 现在我在理解多型方面有点困难,但在学习了Haskell之后,这就是我对它的理解: 类型本身有类型。形式上类型的类型称为种类(即有不同种类的类型) 具体类型(如int和string)和
int
或string
)或类型变量(如α
和β
)int
和string
)或类型构造函数(如Map
和Set
)α
和β
)充当具体类型的占位符(如int
和字符串
)int
和string
)和类型变量(如α
和β
)属于*
类型Map
和Set
)是类型的lambda抽象(例如Set
是类*->*
和Map
是类*->*->*
)∀α、 σ
表示什么?我似乎无法理解它的头绪,我越是读下面的一段,就越感到困惑:
具有polytype∀α、 相比之下,α->α可以将相同类型的任何值映射到自身,并且是该类型的值。另一个例子是∀α、 (集合α)->int是将所有有限集合映射为整数的函数类型。成员计数是此类型的值。请注意,限定符只能出现在顶层,即类型∀α.α -> ∀α、 例如,类型的语法排除了α,而单类型包含在多类型中,因此类型具有一般形式∀α₁ . . . ∀αₙ.τ
首先,种类和多态类型是不同的。你可以有一个HM类型系统,其中所有类型都是相同的(*),你也可以有一个没有多态性但类型复杂的系统 如果术语
M
属于∀a、 t
,这意味着对于任何类型的s
,我们都可以在t
中用s
代替a
(通常写为t[a:=s]
,我们将得到M
是t[a:=s]类型的
。这有点类似于逻辑,在逻辑中,我们可以用任何术语替换通用量化变量,但这里我们讨论的是类型
这正是Haskell中发生的情况,只是在Haskell中你看不到量词。类型签名中出现的所有类型变量都是隐式量化的,就像你在类型前面有forall
一样。例如,map
会有类型
map::全部a.全部b.(a->b)->[a]->[b]
等等。如果没有这种隐含的通用量化,类型变量a
和b
将必须具有某种固定的含义,并且map
不会是多态的
HM算法区分类型(不带量词、单类型)和类型模式(通用量化类型、多类型)。重要的是,在某些地方它使用类型模式(如在let
),但在其他地方只允许使用类型。这使整件事可以判定
我还建议您阅读这篇文章。这是一个更复杂的系统,它允许所有类型中的
都是(因此所有类型都称为type),但类型推断/检查是不可判定的。它可以帮助您了解所有
的工作原理。Girard、Lafont和Taylor对系统F进行了深入描述。考虑Haskell中的l=\x->t
。它是一个lambda,表示一个术语t
,它包含一个变量x
,稍后将被替换(例如,l1
,无论它是什么意思)。同样地,∀α、 σ
表示具有类型变量α
的类型,即f:∀α、 σ
如果由类型α
参数化的函数。在某种意义上,σ
依赖于α
,因此f
返回类型σ(α)
的值,其中α
将在σ(α)
中替换,我们将得到一些具体的类型
在Haskell中,您可以省略∀编码>并定义类似于id:a->a
的函数。允许省略量词的原因基本上是因为它们只允许在顶层使用(没有RankNTypes
扩展)。您可以尝试以下代码:
id2 : a -> a -- I named it id2 since id is already defined in Prelude
id2 x = x
如果您向ghci询问id
(:t id
)的类型,它将返回a->a
。更准确地说(更符合类型理论),id
具有∀a、 a->a
。现在,如果向代码中添加:
val = id2 3
,3具有类型Int
,因此类型Int
将被替换为σ
,我们将得到关于Haskell中类型量化的具体类型Int->Int
,可以成为一个有价值的发现。系统F的类型推理是不可判定的,但类型检查很容易(如果通过类型检查,我们的意思是用类型对术语进行注释,我们只是检查这些注释是否有意义)。@augustss通过类型检查,意味着您获得了一个未注释的术语(咖喱风格)还有一个类型,你应该确定这个术语是否符合这个类型。这也是不可判定的,正如Joe Wells在《佩特普德拉克》中所证明的那样。@PetrPudlák我知道这是不可判定的。很多人把类型检验称为检验教堂风格术语是否有效的过程,所以