实现类型推断


91

我在这里看到了一些有关静态类型与动态类型的有趣讨论。由于编译类型检查,更好的文档代码等,我通常更喜欢静态类型。但是,我同意,例如,如果采用Java的方式完成代码,它们会使代码混乱。

因此,我将开始构建自己的功能样式语言,而类型推断是我要实现的事情之一。我确实知道这是一个很大的主题,并且我不尝试创建以前没有做过的事情,只是进行基本推理...

关于如何阅读的任何指示都可以帮助我解决这个问题?最好是一些比较实用/实用的东西,而不是更多的理论范畴论/类型理论课本。如果那里有一个实施讨论文本,以及数据结构/算法,那将是很可爱的。


1
正是我要找的问题,给出了一些很好的答案!
Paul Hollingsworth,2009年

Answers:


90

我发现以下资源有助于以递增的顺序理解类型推断:

  1. 可免费获得的书PLAI第30章(类型推断),《编程语言:应用和解释》基于统一的类型推断。
  2. 暑期课程将类型解释为抽象值介绍了使用Haskell作为元语言的优雅的评估器,类型检查器,类型重构器和推断器。
  3. 第7章(类型)的书EOPL编程语言的精华
  4. TAPL一书的第22章(类型重构),类型和编程语言以及相应的OCaml实现reconfullrecon
  5. 第13章(类型重建)的新书DCPL在编程语言设计概念
  6. 学术论文的选择
  7. Closure编译器的TypeInference是数据流分析方法以进行类型推断的示例,它比Hindler Milner方法更适合于动态语言。

但是,由于最好的学习方法是学习,因此我强烈建议通过完成编程语言课程的家庭作业来实现玩具功能语言的类型推断。

我推荐ML中的这两项可访问的作业,您都可以在不到一天的时间内完成它们:

  1. PCF解释器一种解决方案)进行预热。
  2. PCF类型推断一种解决方案),用于实现Hindley-Milner类型推断的算法W。

这些作业来自更高级的课程:

  1. 实施MiniML

  2. 多态,存在,递归类型(PDF)

  3. 双向类型检查(PDF)

  4. 子类型和对象(PDF)


2
仅仅是我吗,还是PLAI描述在很大程度上不正确/不完整?该讲座增加了一些内容,但似乎仍不足以使其起作用。
宫坂丽(Rei Miyasaka)

我也无法在PLAI书的2012年版中获得该算法。约束列表没有替代项。取而代之的是,我在PLAI书的2003-7版中实现了类型推断算法,它看起来效果更好,并且可以很好地扩展到let多态性。
heykell

28

不幸的是,有关该主题的许多文献都非常密集。我也是在你的鞋子。我从“编程语言:应用程序和解释”中对该主题进行了首次介绍。

http://www.plai.org/

我将尝试总结抽象的想法,然后总结一些我没有立即发现的细节。首先,可以考虑类型推断来生成约束,然后求解约束。要生成约束,请遍历语法树并在每个节点上生成一个或多个约束。例如,如果节点是+运算符,则操作数和结果都必须为数字。应用功能的节点的类型与功能的结果相同,依此类推。

对于没有的语言let,您可以通过替换盲目解决上述限制。例如:

(if (= 1 2) 
    1 
    2)

在这里,我们可以说if语句的条件必须为布尔值,并且if语句的类型与其thenelse子句的类型相同。因为我们知道1并且2是数字,所以通过代入,我们知道if语句是数字。

事情变得令人讨厌,而我一时不了解的地方正在处理let:

(let ((id (lambda (x) x)))
    (id id))

在这里,我们绑定id了一个函数,该函数返回您传入的所有内容,或者称为身份函数。问题在于x,每次使用时,函数参数的类型都不同id。第二个id是type的函数a -> a,其中a可以是任何东西。第一个是type (a -> a) -> (a -> a)。这称为let多态性。关键是按特定顺序解决约束:首先解决的定义的约束id。这将是a -> a。然后,id可以使用的类型的新的独立副本替换每个位置的约束id,例如a2 -> a2a3 -> a3

在线资源中并没有很容易解释这一点。他们将提到算法W或M,但没有提到它们在解决约束方面的工作方式,或者为什么它不会阻碍let多态性:每种算法都在解决约束时强制执行排序。

我发现该资源对于将算法W,M以及约束生成和求解的一般概念结合在一起非常有帮助。它有点密集,但比许多要好:

http://www.cs.uu.nl/research/techreps/repo/CS-2002/2002-031.pdf

那里的许多其他论文也很好:

http://people.cs.uu.nl/bastiaan/papers.html

我希望这有助于澄清一个有点模糊的世界。


7

除了用于功能语言的Hindley Milner外,另一种流行的动态语言类型推断方法是 abstract interpretation

抽象解释的思想是为语言编写一种特殊的解释器,而不是保留具体值(1,false,closure)的环境,而是对抽象值,aka类型(int,bool等)起作用。由于它是根据抽象值来解释程序,因此将其称为抽象解释。

Pysonar2是Python抽象解释的一种优雅实现。Google用来分析Python项目。基本上,它用于visitor pattern将评估调用调度到相关的AST节点。visitor函数transform 接受将context在其中评估当前节点的,并返回当前节点的类型。



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.