我正在为连接语言开发编译器,并希望添加类型推断支持。我了解Hindley–Milner,但是我一直在学习类型理论,所以我不确定如何适应它。以下系统是否合理,可以推断?
术语是文字,术语的组合,术语的引用或基元。
所有术语表示功能。对于两个函数和,,即,并置表示反向组合。文字表示尼拉德功能。e 2 e 1
除组合以外的其他术语具有基本的类型规则:
值得注意的是缺少应用规则,因为连接语言缺少它。
类型可以是文字,类型变量,也可以是堆栈之间的函数,其中堆栈被定义为右嵌套元组。相对于“堆栈其余部分”,所有函数都是隐式多态的。
这是第一件事,似乎是可疑的,但我不知道到底是怎么了。
为了帮助可读性和括号砍了,我假设在类型方案中, b = b × (a )。我还将大写字母用于表示堆栈的变量,而不是单个值。
有六个原语。前五个非常无害。dup
取最高值并产生两个副本。swap
更改前两个值的顺序。pop
放弃最高价值。quote
接受一个值并产生一个引号(函数),将其返回。apply
将报价应用于堆栈。
最后一个组合compose
符应当接受两个引号,并返回其串联的类型,即。在静态类型的连接语言Cat中,的类型非常简单。compose
但是,这种类型的限制太多:它要求第一个函数的产生与第二个函数的消耗完全匹配。实际上,您必须假设不同的类型,然后统一它们。但是,您将如何编写该类型?
如果让表示两种类型的差异,那么我认为您可以正确地编写类型。compose
这仍然相对简单:compose
采用函数和一个f 2:D → E。其结果消耗乙的消耗顶上˚F 2不通过产生˚F 1,并产生d生产的顶上˚F 1不是由消耗˚F 2。这给出了普通构图的规则。
但是,我不知道这个假设的实际上与任何事物都对应,并且我一直在圈内追逐它很长时间,以至于我认为我走错了方向。这可能是元组的简单区别吗?
我没有看到与此有关的可怕问题,还是我走在正确的道路上?(我可能错误地量化了其中的一些内容,并且希望在该领域进行修复。)
compose
太严格?我的印象是这样很好。(例如,限制可以像在λ微积分中那样通过统一处理)
twice
定义为dup compose apply
,它会引用并应用两次。[1 +] twice
是好的:你排版的两个功能。但并非如此:如果∀ 一b 。[pop] twice
,问题在于 A ≠ A,所以表达式是不允许的,即使它应该是有效的,并有型 ∀ 甲b 。。解决方案当然是将限定词放在正确的位置,但是我主要是想知道如何在没有任何循环定义的情况下实际编写类型。compose