产品类型的类型推断


15

我正在为连接语言开发编译器,并希望添加类型推断支持。我了解Hindley–Milner,但是我一直在学习类型理论,所以我不确定如何适应它。以下系统是否合理,可以推断?

术语是文字,术语的组合,术语的引用或基元。

e::=x|ee|[e]|

所有术语表示功能。对于两个函数和,,即,并置表示反向组合。文字表示尼拉德功能。e 2 e 1e1e2e1e2=e2e1

除组合以外的其他术语具有基本的类型规则:

x:ι[Lit]Γe:σΓ[e]:α.ασ×α[Quot],α not free in Γ

值得注意的是缺少应用规则,因为连接语言缺少它。

类型可以是文字,类型变量,也可以是堆栈之间的函数,其中堆栈被定义为右嵌套元组。相对于“堆栈其余部分”,所有函数都是隐式多态的。

τ:: =ι|α|ρρρ:: =|τ×ρσ:: =τ|ασ

这是第一件事,似乎是可疑的,但我不知道到底是怎么了。

为了帮助可读性和括号砍了,我假设一种b=b×一种在类型方案中, b = b × a 。我还将大写字母用于表示堆栈的变量,而不是单个值。

有六个原语。前五个非常无害。dup取最高值并产生两个副本。swap更改前两个值的顺序。pop放弃最高价值。quote接受一个值并产生一个引号(函数),将其返回。apply将报价应用于堆栈。

düp::一种b一种b一种bbsw一种p::一种bC一种bC一种CbpØp::一种b一种b一种qüØŤË::一种b一种b一种CCCb一种ppÿ::一种一种一种

最后一个组合compose符应当接受两个引号,并返回其串联的类型,即。在静态类型的连接语言Cat中,的类型非常简单。[Ë1][Ë2]CØpØsË=[Ë1Ë2]compose

CØpØsË::一种Cd一种CCd一种d

但是,这种类型的限制太多:它要求第一个函数的产生与第二个函数的消耗完全匹配。实际上,您必须假设不同的类型,然后统一它们。但是,您将如何编写该类型?

CØpØsË::一种CdË一种CdË一种

如果让表示两种类型的差异,那么我认为您可以正确地编写类型。compose

CØpØsË::一种CdË一种CdË一种dCCdË

这仍然相对简单:compose采用函数和一个f 2D E。其结果消耗的消耗顶上˚F 2不通过产生˚F 1,并产生d生产的顶上˚F 1不是由消耗˚F 2。这给出了普通构图的规则。F1CF2dËF2F1dF1F2

Γe1:AB.ABΓe2:CD.CDΓe1e2:((CB)A((BC)D))[Comp]

但是,我不知道这个假设的实际上与任何事物都对应,并且我一直在圈内追逐它很长时间,以至于我认为我走错了方向。这可能是元组的简单区别吗?

一种一种=一种一种=一种一种Cd一种Cd=d iff 一种=C除此以外=未定义

我没有看到与此有关的可怕问题,还是我走在正确的道路上?(我可能错误地量化了其中的一些内容,并且希望在该领域进行修复。)


您如何在语法中使用变量?这个问题应该可以帮助您处理似乎需要的“子类型化”。
jmad 2012年

1
@jmad:我不确定我是否理解这个问题。类型变量只是为了正式定义类型方案而存在,语言本身根本没有变量,只有定义,可以[相互]递归。
乔恩·普迪

很公平。你能说为什么(也许举个例子)规则compose太严格?我的印象是这样很好。(例如,限制可以像在λ微积分中那样通过统一处理)C=d
jmad 2012年

@jmad:好的。考虑twice定义为dup compose apply,它会引用并应用两次。[1 +] twice是好的:你排版的两个功能。但并非如此:如果b ιι[pop] twice,问题在于 A AAb.f1,f2:AbA,所以表达式是不允许的,即使它应该是有效的,并有型b AAb。解决方案当然是将限定词放在正确的位置,但是我主要是想知道如何在没有任何循环定义的情况下实际编写类型。Ab.AbbAcompose
乔恩·普迪

Answers:


9

下面秩2型 似乎是足够通用。它比问题中提出的类型多态得多。此处变量对堆栈的连续块进行量化,从而捕获了多参数函数。

compose:ABCδ.δ (α.α AαB) (β.β BβC)δ (γ.γ AγC)

希腊字母用于其余的堆栈变量,只是为了清楚起见。

它表达了约束,即堆栈中第一个元素的输出堆栈需要与第二个元素的输入堆栈相同。正确实例化两个实际参数的变量是一种使约束正常工作的方法,而不是像您在问题中提出的那样定义新的操作。B

我认为,尽管已经完成了一些工作,在实践中会产生良好的结果(对于Haskell),但一般来说,类型检查级别2的类型是不确定的:

  • Simon L. Peyton Jones,Dimitrios Vytiniotis,Stephanie Weirich,Mark Shields:任意等级类型的实用类型推断。J.功能 程序。17(1):1-82(2007)

组成的类型规则很简单:

Γe1:α.α Aα BΓe1:α.α Bα CΓe1 e2:α.α Aα C

为了使类型系统能够正常工作,您需要以下专门化规则:

Γe:α.α Aα BΓe:α.C Aα C B

dup +ιι+ιιι

1
堆栈类型对堆栈碎片进行量化,因此处理两个自变量函数没有问题。我不确定这如何应用于dup +,因为它不使用您在上面定义的compose。
戴夫·克拉克

[dup] [+] composeαBB×αB=ι×ι(ι×ι)×αι×(ι×α)

我可能在错误的方向上构建堆栈。我认为嵌套并不重要,只要建立堆栈的对不出现在编程语言中即可。(我打算更新我的答案,但需要先做一点研究。)
Dave Clarke 2012年

是的,嵌套几乎是一个实现细节。
乔恩·普迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.