族谱网 头条 人物百科

类型推论

2020-10-16
出处:族谱网
作者:阿族小谱
浏览:206
转发:0
评论:0
非技术性解说在大多数的编程语言中,所有值都有一个类型,它描述特定值的数据种类。在一些语言中,表达式的类型只在运行时才知道;这些语言被称作动态类型语言。而另一些语言中,表达式的类型在编译时就知道,这些语言叫做静态类型语言。在静态类型语言中,函数的输入和输出与局部变量的类型一般必须用类型标注明确的提供。例如,在C语言中:intaddone(intx){intresult;/*声明整数result(C语言)*/result=x+1;returnresult;}这个函数定义开始处,intaddone(intx)声明了addone是函数,接受一个整数类型的参数,并返回一个整数。intresult;声明了局部变量result是个整数。在支持类型推论的建议的语言中,代码可写为如下:这看起来非常像在动态类型语言中写出的代码,但是提供了一些额外的约束(见下)使得能够在编译时推断出所有变量的类型。在上面的例子...

非技术性解说

在大多数的编程语言中,所有值都有一个类型,它描述特定值的数据种类。在一些语言中,表达式的类型只在运行时才知道;这些语言被称作动态类型语言。而另一些语言中,表达式的类型在编译时就知道,这些语言叫做静态类型语言。在静态类型语言中,函数的输入和输出与局部变量的类型一般必须用类型标注明确的提供。例如,在C语言中:

intaddone(intx){intresult;/*声明整数 result (C 语言)*/result=x+1;returnresult;}

这个函数定义开始处,int addone(int x) 声明了 addone 是函数,接受一个整数类型的参数,并返回一个整数。int result; 声明了局部变量 result 是个整数。在支持类型推论的建议的语言中,代码可写为如下:

这看起来非常像在动态类型语言中写出的代码,但是提供了一些额外的约束(见下)使得能够在编译时推断出所有变量的类型。在上面的例子中,因为+ 总是接受两个整数并返回一个整数。编译器可以推论出 x+1 的值是个整数,因此 result 是个整数,addone 的返回值是个整数。类似的,因为 + 要求它的两个实际参数都是整数,x 必须是整数,因此 addone 接受一个整数实际参数。

但是在随后一行中 result2 加上了一个浮点数 "1.",导致了 x 同时用于整数和浮点数的冲突。这种情况将生成编译时间错误消息。在老语言中,result2 可以被隐含的声明为浮点变量,通过隐含的转换表达式中的整数 x,简单的因为小数点意外的被放到了整数 1 的后面。这种情况说明了二者之间的区别,“类型推论”不涉及类型转换,而“隐含类型转换”经常没有限制的把数据强制成高精度的数据类型。

技术描述

类型推论指的是要么部分要么完全自动演绎的能力,把值的类型从表达式的最终计算中推导出来。因为这个过程在编译时间系统性的进行,编译器经常能推出变量的类型或函数的类型标署,而不用给出明确的类型标注。在很多情况下,如果推论系统足够强壮或程序足够简单,有可能完全从程序中省略类型标注。

要获得正确推导出缺乏类型标注的一个表达式的类型所必要的信息,编译器要么随着给它的子表达式(它们自身可以是变量或函数)的类型标注的聚集(aggregate)和后续简约来收集这种信息,要么通过各种原子值的类型的隐含理解(比如 () : 单位; true : 布尔; 42 : 整数; 3.14159 : 实数; 等等)。通过表达式的最终简约到隐含类型原子值的识别,类型推论语言的编译器有能力编译完全没有类型标注的程序。在高阶编程和多态性的高度复杂的情况下,编译器不能总是如此推论,偶尔需要类型标注来去除歧义。

例子

例如,考虑Haskell函数 map,它把一个函数应用于一个列表的每个元素上,它可定义为:

明显的函数 map 接受一个列表作为第二个实际参数,它的第一个实际参数 f 是可以应用于这个列表的元素的类型上函数,而 map 的结果被构造为其元素是 f 的结果的一列表。所以假定列表包含同样类型的元素,我们能可靠的构造出类型标署

这里的语法 "a->b" 指示接受 a 作为它的形式参数并生成 b 的一个过程。 "a->b->c" 等价于 "a->(b->c)"。

注意 map 的推论类型是参数化多态的: 实际参数和 f 的结果的类型是不推出的,而是留作类型变量,所以 map 可以应用于各种类型的函数和列表,只要在每次调用中实际类型是匹配的。

Hindley–Milner 类型推论算法

进行类型推论的常用算法是 Hindley–Milner 或 Damas–Milner 算法。

这个算法的起源是 Haskell B. Curry 和 Robert Feys 在1958年为简单类型lambda演算设计的类型推论算法。在 1969 年 Roger Hindley 扩展了这项工作并证明他们的算法总能推出最一般的类型。在 1978 年 Robin Milner,独立于 Hindley 的工作,提供了等价的算法。在 1985 年 Luis Damas 最终证明了 Milner 的算法是完备的并扩展它来支持带有多态引用的系统。

算法

算法过程分两个步骤。首先需要生成一些要解的方程,接着解它们。

生成方程

用来生成方程的算法类似与正规的类型检查器,所以我们首先如下有类型lambda演算的正规类型检查器:

e ::= E ∣ ∣ --> v ∣ ∣ --> ( λ λ --> v : τ τ --> . e ) ∣ ∣ --> ( e e ) {\displaystyle e\,::=E\mid v\mid (\lambda v:\tau .e)\mid (e\,e)}

τ τ --> ::= T ∣ ∣ --> τ τ --> → → --> τ τ --> {\displaystyle \tau \,::=T\mid \tau \to \tau }

这里的 E {\displaystyle E} 是原始表达式 (比如 "3") 而 T {\displaystyle T} 是原始类型 (比如 "Integer")。

我们希望构造有类型 ( ϵ ϵ --> , t ) → → --> τ τ --> {\displaystyle (\epsilon ,t)\to \tau } 的一个函数 f {\displaystyle f} ,这里的 ϵ ϵ --> {\displaystyle \epsilon } 是类型环境而 t {\displaystyle t} 是一个项。我们假定这个函数已经定义在原始表达式上。其他情况有:

f ( ϵ ϵ --> , v ) = τ τ --> {\displaystyle f(\epsilon ,v)=\tau } 这里的 ( v , τ τ --> ) {\displaystyle (v,\tau )} 在 ϵ ϵ --> {\displaystyle \epsilon } 中

f ( ϵ ϵ --> , g e ) = τ τ --> {\displaystyle f(\epsilon ,g\,e)=\tau } 这里的 f ( ϵ ϵ --> , g ) = τ τ --> 1 → → --> τ τ --> {\displaystyle f(\epsilon ,g)=\tau _{1}\to \tau } 且 f ( ϵ ϵ --> , e ) = τ τ --> 1 {\displaystyle f(\epsilon ,e)=\tau _{1}}

f ( ϵ ϵ --> , λ λ --> v : τ τ --> . e ) = τ τ --> → → --> f ( ϵ ϵ --> 1 , e ) {\displaystyle f(\epsilon ,\lambda v:\tau .e)=\tau \to f(\epsilon _{1},e)} 这里的 ϵ ϵ --> 1 = ϵ ϵ --> ∪ ∪ --> ( v , τ τ --> ) {\displaystyle \epsilon _{1}=\epsilon \cup (v,\tau )}

注意我们至今没有指定在不能满足各种条件的时候做什么。这是因为,在简单类型检查算法中,检查在任何事情出错的时候都失败。

现在,我们开发一个更复杂的算法来处理类型变量和在它们上的约束。所以,我们扩展原始类型的集合 T 来包括变量的无限补给,指示为小写希腊字母 α α --> , β β --> , . . . {\displaystyle \alpha ,\beta ,...} 。详情参见 。

解方程

解方程通过合一进行。可能令人惊奇,这是个非常简单的算法。函数 u {\displaystyle u} 运算在类型方式上并返回叫做“代换”的一个结构。代换简单是一从类型变量到类型的一个映射。代换可以用明显的方式组成和扩展。

合一方程的空集是足够容易的: u ∅ ∅ --> = i {\displaystyle u\,\emptyset =\mathbf {i} } ,这里的 i {\displaystyle \mathbf {i} } 是同一代换。

合一变量与类型以如下方式进行: u ( [ α α --> = T ] ∪ ∪ --> C ) = u ( C ′ ) ⋅ ⋅ --> ( α α --> ↦ ↦ --> T ) {\displaystyle u\,([\alpha =T]\cup C)=u\,(C")\cdot (\alpha \mapsto T)} ,这里的 ⋅ ⋅ --> {\displaystyle \cdot } 是代换合成算子,而 C ′ {\displaystyle C"} 是保持约束 C {\displaystyle C} 于应用到它的新代换 α α --> ↦ ↦ --> T {\displaystyle \alpha \mapsto T} 的集合。

当然 u ( [ T = α α --> ] ∪ ∪ --> C ) = u ( [ α α --> = T ] ∪ ∪ --> C ) {\displaystyle u\,([T=\alpha ]\cup C)=u([\alpha =T]\cup C)} 。

有趣的情况保持为 u ( [ S → → --> S ′ = T → → --> T ′ ] ∪ ∪ --> C ) = u ( { [ S = T ] , [ S ′ = T ′ ] } ∪ ∪ --> C ) {\displaystyle u\,([S\to S"=T\to T"]\cup C)=u\,(\{[S=T],[S"=T"]\}\cup C)} 。


免责声明:以上内容版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。感谢每一位辛勤著写的作者,感谢每一位的分享。

——— 没有了 ———
编辑:阿族小谱
发表评论
写好了,提交
{{item.label}}
{{commentTotal}}条评论
{{item.userName}}
发布时间:{{item.time}}
{{item.content}}
回复
举报
点击加载更多
打赏作者
“感谢您的打赏,我会更努力的创作”
— 请选择您要打赏的金额 —
{{item.label}}
{{item.label}}
打赏成功!
“感谢您的打赏,我会更努力的创作”
返回

更多文章

更多精彩文章
打赏
私信

推荐阅读

· 推论
参见逻辑推理
· 推论统计学
参考文献延伸阅读CasellaG.BergerRL(2001).StatisticalInference.DuxburyPress.ISBN0534243126Cox,D.R.(2006).PrinciplesofStatisticalInference,CUP.ISBN0-521-68567-2Lenhard,Johannes(2006)."ModelsandStatisticalInference:TheControversybetweenFisherandNeyman—Pearson,"BritishJournalforthePhilosophyofScience,Vol.57Issue1,pp.69-91.Sudderth,WilliamD.(1994)."CoherentInferenceandPredictioninStatistics,"inPrawitz,Skyrms,an...
· 班固、班超的兄弟关系推论
班彪,班固和班超,是我国历史上家喻户晓的名人,因为一门父子三人都在历史上有所作为,长期以来传为佳话。现行高中历史教材中主要涉及到三班中的班固和班超。班固是东汉史学家是中历史上第一部断代史《汉书》的主要作者,班超是东汉著名的军事家和外交家。班固和班超的兄弟关系一直以来众说纷纭,然则空说无凭,盲目下定义也属失察失责,以下推论乞共商唷翻开《辞海》,找到班固、班超的介绍如下:班固(公元32―92)字孟坚。扶风安陵(今陕西咸阳东北)人。东汉史学家。班超(公元32―102),字仲升,扶风安陵(今陕西咸阳东北)人,东汉著名的军事家和外交家。由此疑问:班固班超是同年出生的兄弟。那么到底班固、班超他们究竟是一种什么样的兄弟关系呢?在正式分析之前,我们首先必须要知道,以上所列材料应该没有问题。班固、班超的兄弟关系是在《汉书》中记载的,班固是《汉书》的主要作者;关于他们在世时间的介绍,包括《辞海》在内的几本权威...
· 类型安全
定义RobinMilner对于类型安全所喊出的口号:这一口号的涵义,取决于语言形式化语义的类别。在指称语义学里,类型安全意谓者一个表达式的值具有良好类型τ,则表达式是一个属于τ的集合的真正的成员。1994年,AndrewWright和MatthiasFelleisen以操作语义学定义的公式描述:何谓现今的标准定义,以及对于类型安全的检验技术。根据上述方法,类型安全是以编程语言语义中的两个性质所决定的:这些性质不是无中生有的,而是和编程语言所描述出来的语义相连系,而且各式各样的语言存在着可以此基准来充实的广大的空间。因为“类型良好”程序的概念已是静态语义学的一部分,而“卡住”(或者“搞错”)则是动态语义学方面的属性。语言的类型安全性学术研究用途的玩具语言,常会提出类型安全方面的需求。另一方面,许多语言以人工方式所产生的类型安全,证实经常需要上千次的检查。不过,某些语言,如标准ML,其严格定义...
· 类型论
类型论体系主要简单类型λ演算,一种高阶逻辑;直觉类型论;系统F;LF经常用来定义其他类型论;构造演算及其派生理论。次要Automath(英语:Automath);ST类型论;组合逻辑的一些形式;λ立方体(英语:Lambdacube)中定义的其他;其他有类型λ演算;其他纯类型系统(英语:puretypesystem)。活跃正在研究中的同伦类型论参考文献延伸阅读Andrews,PeterB.,2002.AnIntroductiontoMathematicalLogicandTypeTheory:ToTruthThroughProof,2nded.KluwerAcademicPublishers.Cardelli,Luca,1997,"TypeSystems,"inAllenB.Tucker,ed.,TheComputerScienceandEngineeringHandbook.CRCPres...

关于我们

关注族谱网 微信公众号,每日及时查看相关推荐,订阅互动等。

APP下载

下载族谱APP 微信公众号,每日及时查看
扫一扫添加客服微信