下连是什么意思| 梦见死人复活什么预兆| 奥氮平片治疗什么病| 军分区司令是什么级别| 为什么头发突然秃了一块| 酒蒙子什么意思| 碱性磷酸酶高是什么意思| 月经每次都推迟是什么原因| 梦见自己牙齿掉了是什么意思| 白细胞十一是什么意思| 净土是什么意思| 月经不正常是什么原因| 言外之意是什么意思| 男人怕冷是什么原因| 寅虎是什么意思| 正印代表什么意思| 女性排卵期一般是什么时候| 点痣后用什么修复最好| 草莓什么季节| 红肉是指什么肉| 支配是什么意思| 女人梦见桃子预示什么| 温居是什么意思| 丙肝是什么| 尿里有红细胞是什么原因| 一冷就咳嗽是什么原因| 云南雪燕有什么作用| 细菌感染用什么药| 精满自溢是什么意思| 超现实主义是什么意思| 喝什么茶降血糖| 肺部气肿吃什么药能治好| hc2是什么检查| 腋下异味用什么药| 螃蟹为什么横着走| sid是什么意思| 角色扮演是什么意思| 八仙过海指什么生肖| 三班倒是什么意思| 为什么睡觉会突然抖一下| 红花泡脚有什么好处| 声带小结是什么意思| 安踏属于什么档次| 什么时候大阅兵| 女人梦见鬼是什么征兆| 徐五行属什么| 家里有小蜘蛛预示什么| 慈禧姓什么| 换气是什么意思| 梦见血是什么意思| 鱼用什么呼吸| 美人坯子是什么意思| 为什么叫犹太人| 什么是败血症| 经期量少吃什么来排血| 煸是什么意思| 胆汁反流用什么药| 心肌炎有什么症状和表现| 胰腺炎不能吃什么食物| 天高云淡是什么季节| 雪燕适合什么人吃| 脸发红是什么原因| 撇嘴是什么意思| 什么是白茶| 反流性食管炎吃什么中药| 偶像是什么意思| 魏丑夫和芈月什么关系| 准备的近义词是什么| 左侧小腹疼是什么原因| 顺风顺水什么意思| 什么变化| 说话声音小是什么原因| 为什么近视| 阴道炎用什么药效果最好| 什么的图案| 眼球有黑色斑点是什么| 分泌物过氧化氢阳性是什么意思| 吃什么会变白| 温饱是什么意思| 宫颈潴留性囊肿是什么| 尹什么意思| 王爷是皇上的什么人| 女生胸痛什么原因| 十二月八号是什么星座| 牙出血什么原因| 现役是什么意思| 什么是丛林法则| 子宫小结节是什么意思| 负数是什么| 一意孤行是什么意思| 尿酸高能吃什么| 什么情况下要做宫腔镜| 棕色配什么颜色| 鼻窦炎是什么原因引起的呢| 端午节在什么时候| 味淋是什么东西| 陈旧性心梗是什么意思| pbo是什么| 汤去掉三点水念什么| 德国是什么民族| 流口水吃什么药最好| 口嫌体正直什么意思| 苹可以组什么词| lsa是什么胎位| 梦见自己洗头发是什么意思| 维生素d和d3有什么区别| 再创佳绩是什么意思| 尿频是什么病| d cup是什么意思| sunglasses是什么意思| 羽五行属什么| ep病毒是什么| 头部ct能检查出什么| 身体缺钾会有什么症状| 牙松动了还疼用什么方法处理最好| 蛋白质是什么意思| 老年人脚肿什么原因| 龙傲天是什么意思| 头一直疼是什么原因| 疑难杂症是什么意思| 羁什么意思| 盗汗什么意思| 六月不搬家是什么意思| 挂帅是什么意思| 甲沟炎属于什么科| 古代上班叫什么| 九七年属什么| 为什么会有痔疮| 黄精为什么要九蒸九晒| 杂菌阳性是什么意思| 牛肉和什么不能一起吃| 余字五行属什么| 蹲久了站起来头晕是什么原因| 凉皮是用什么做的| 汗疱疹是什么原因引起的| 嘴角起泡用什么药膏好| 什么龙什么虎| 医院总务科是干什么的| 什么高什么下| 晒伤了涂什么药| 4月3日什么星座| 世界上有什么| 浪琴军旗什么档次| 天赋异禀什么意思| 五个月宝宝吃什么辅食最好| 6度醋与9度有什么区别| 岁月蹉跎什么意思| 乡镇派出所所长是什么级别| 鱼完念什么| 胃烧灼感吃什么药| 你为什么背着我爱别人| 阿戈美拉汀片是什么药| 染色体异常是什么原因导致的| 盆腔积液是什么意思| 腱鞘炎要挂什么科| 讨吃货什么意思| 12月25日是什么日子| 十加一笔是什么字| 没有子宫有什么影响| 咳嗽挂什么科室| 私奔什么意思| 鸡血藤长什么样子图片| 视野是什么意思| 中度脂肪肝吃什么药| 黄花苗泡水喝有什么作用| 阳光明媚是什么意思| 什么是躯体化症状表现| 沙特用什么货币| 双子座是什么时候| 龙涎香是什么| 平台期是什么意思| 皮肤过敏用什么药最好| 梦见一群羊是什么意思| 男人吃四环素治什么病| 胃酸过多是什么原因造成的| 授受不亲什么意思| 鱼条念什么| 松花粉有什么功效| date是什么意思| 6月23日是什么星座| hp代表什么意思| 跌跌撞撞什么意思| 长期胃胀气什么原因| 63岁属什么生肖| 多发淋巴结是什么意思| 秀才相当于什么学历| MS医学上是什么意思| 什么凌乱| 千千阙歌是什么意思| 月的偏旁有什么字| 黄辣丁吃什么食物| 西瓜什么季节成熟| 肌酐低是什么问题| 代糖是什么| 讲信修什么| 手指头麻木吃什么药| 煲仔饭用什么米最好| 过年吃什么| 丢包是什么意思| omega3是什么| 耳道湿疹用什么药| 舌头凉凉的是什么原因| 什么叫钙化| act什么意思| 切痣挂什么科| 金牛男喜欢什么类型的女生| 看腋臭挂什么科| 顾虑是什么意思| 敏感的反义词是什么| zbc什么意思| 什么菜补血| 什么舌头| 尿渗透压低是什么原因| 尿黄是什么病| 狗上皮过敏是什么意思| 什么入什么口| 吃什么补钙最快| 梦见和老公吵架是什么意思| 小便短赤是什么症状| 怀孕了有什么征兆| 绿巨人是什么意思| 小孩肺炎吃什么药| 抹茶色是什么颜色| 办银行卡需要什么证件| 甲亢有些什么症状| 什么叫卒中| 皮肤白斑是什么原因| 庸医是什么意思| 6月18是什么星座| 血糖高能喝什么粥| 金鱼的尾巴像什么| 靶向治疗是什么意思| 口腔医学是干什么的| 经常想吐恶心是什么原因| 经期吃什么水果比较好| 叩齿是什么意思| bl是什么意思| 讨好的笑是什么笑| 鼓的偏旁部首是什么| 怀孕两周有什么症状| 为什么偏偏喜欢你| 什么是做功| 中国的全称是什么| 胚胎生化是什么意思| 内分泌科看什么| 白术有什么功效| 什么天山| 二尖瓣反流什么意思| 棱长是什么| 撬墙角是什么意思| 血糖高初期有什么症状| 儿童抗o高会引起什么病| 老公生日送什么礼物好| 什么东西清肺止咳| 椰青是什么| 吃饭恶心想吐是什么原因| 橡皮擦是什么材料做的| 干咳嗽吃什么药| 水泡长什么样子图片| 什么的绽放| 15是什么意思| 蚂蚁搬家是什么意思| ooc是什么意思| 精髓是什么意思| 百度Jump to content

贵州省省级政府透明度指数排名全国第一

From Wikipedia, the free encyclopedia
百度 商务频道介绍  电子商务发展的繁荣,为互联网经济注入了强大的活力。

Type inference, sometimes called type reconstruction,[1]:?320? refers to the automatic detection of the type of an expression in a formal language. These include programming languages and mathematical type systems, but also natural languages in some branches of computer science and linguistics.

Nontechnical explanation

[edit]

In a typed language, a term's type determines the ways it can and cannot be used in that language. For example, consider the English language and terms that could fill in the blank in the phrase "sing _." The term "a song" is of singable type, so it could be placed in the blank to form a meaningful phrase: "sing a song." On the other hand, the term "a friend" does not have the singable type, so "sing a friend" is nonsense. At best it might be metaphor; bending type rules is a feature of poetic language.

A term's type can also affect the interpretation of operations involving that term. For instance, "a song" is of composable type, so we interpret it as the thing created in the phrase "write a song". On the other hand, "a friend" is of recipient type, so we interpret it as the addressee in the phrase "write a friend". In normal language, we would be surprised if "write a song" meant addressing a letter to a song or "write a friend" meant drafting a friend on paper.

Terms with different types can even refer to materially the same thing. For example, we would interpret "to hang up the clothes line" as putting it into use, but "to hang up the leash" as putting it away, even though, in context, both "clothes line" and "leash" might refer the same rope, just at different times.

Typings are often used to prevent an object from being considered too generally. For instance, if the type system treats all numbers as the same, then a programmer who accidentally writes code where 4 is supposed to mean "4 seconds" but is interpreted as "4 meters" would have no warning of their mistake until it caused problems at runtime. By incorporating units into the type system, these mistakes can be detected much earlier. As another example, Russell's paradox arises when anything can be a set element and any predicate can define a set, but more careful typing gives several ways to resolve the paradox. In fact, Russell's paradox sparked early versions of type theory.

There are several ways that a term can get its type:

  • The type might be provided from somewhere outside the passage. For instance, if a speaker refers to "a song" in English, they generally do not have to tell the listener that "a song" is singable and composable; that information is part of their shared background knowledge.
  • The type can be declared explicitly. For example, a programmer might write a statement like delay: seconds := 4 in their code, where the colon is the conventional mathematical symbol to mark a term with its type. That is, this statement is not only setting delay to the value 4, but the delay: seconds part also indicates that delay's type is an amount of time in seconds.
  • The type can be inferred from context. For example, in the phrase "I bought it for a song", we can observe that trying to give the term "a song" types like "singable" and "composable" would lead to nonsense, whereas the type "amount of currency" works out. Therefore, without having to be told, we conclude that "song" here must mean "little to nothing", as in the English idiom "for a song", not "a piece of music, usually with lyrics".

Especially in programming languages, there may not be much shared background knowledge available to the computer. In manifestly typed languages, this means that most types have to be declared explicitly. Type inference aims to alleviate this burden, freeing the author from declaring types that the computer should be able to deduce from context.

Type-checking vs. type-inference

[edit]

In a typing, an expression E is opposed to a type T, formally written as E : T. Usually a typing only makes sense within some context, which is omitted here.

In this setting, the following questions are of particular interest:

  1. E : T? In this case, both an expression E and a type T are given. Now, is E really a T? This scenario is known as type-checking.
  2. E : _? Here, only the expression is known. If there is a way to derive a type for E, then we have accomplished type inference.
  3. _ : T? The other way round. Given only a type, is there any expression for it or does the type have no values? Is there any example of a T? This is known as type inhabitation.

For the simply typed lambda calculus, all three questions are decidable. The situation is not as comfortable when more expressive types are allowed.

Types in programming languages

[edit]

Types are a feature present in some strongly statically typed languages. It is often characteristic of functional programming languages in general. Some languages that include type inference include C23,[2] C++11,[3] C# (starting with version 3.0), Chapel, Clean, Crystal, D, Dart,[4] F#,[5] FreeBASIC, Go, Haskell, Java (starting with version 10), Julia,[6] Kotlin,[7] ML, Nim, OCaml, Opa, Q#, RPython, Rust,[8] Scala,[9] Swift,[10] TypeScript,[11] Vala,[12] Zig, and Visual Basic[13] (starting with version 9.0). The majority of them use a simple form of type inference; the Hindley–Milner type system can provide more complete type inference. The ability to infer types automatically makes many programming tasks easier, leaving the programmer free to omit type annotations while still permitting type checking.

In some programming languages, all values have a data type explicitly declared at compile time, limiting the values a particular expression can take on at run-time. Increasingly, just-in-time compilation blurs the distinction between run time and compile time. However, historically, if the type of a value is known only at run-time, these languages are dynamically typed. In other languages, the type of an expression is known only at compile time; these languages are statically typed. In most statically typed languages, the input and output types of functions and local variables ordinarily must be explicitly provided by type annotations. For example, in ANSI C:

int add_one(int x) {
    int result; /* declare integer result */

    result = x + 1;
    return result;
}

The signature of this function definition, int add_one(int x), declares that add_one is a function that takes one argument, an integer, and returns an integer. int result; declares that the local variable result is an integer. In a hypothetical language supporting type inference, the code might be written like this instead:

add_one(x) {
    var result;  /* inferred-type variable result */
    var result2; /* inferred-type variable result #2 */

    result = x + 1;
    result2 = x + 1.0;  /* this line won't work (in the proposed language) */
    return result;
}

This is identical to how code is written in the language Dart, except that it is subject to some added constraints as described below. It would be possible to infer the types of all the variables at compile time. In the example above, the compiler would infer that result and x have type integer since the constant 1 is type integer, and hence that add_one is a function int -> int. The variable result2 isn't used in a legal manner, so it wouldn't have a type.

In the imaginary language in which the last example is written, the compiler would assume that, in the absence of information to the contrary, + takes two integers and returns one integer. (This is how it works in, for example, OCaml.) From this, the type inferencer can infer that the type of x + 1 is an integer, which means result is an integer and thus the return value of add_one is an integer. Similarly, since + requires both of its arguments be of the same type, x must be an integer, and thus, add_one accepts one integer as an argument.

However, in the subsequent line, result2 is calculated by adding a decimal 1.0 with floating-point arithmetic, causing a conflict in the use of x for both integer and floating-point expressions. The correct type-inference algorithm for such a situation has been known since 1958 and has been known to be correct since 1982. It revisits the prior inferences and uses the most general type from the outset: in this case floating-point. This can however have detrimental implications, for instance using a floating-point from the outset can introduce precision issues that would have not been there with an integer type.

Frequently, however, degenerate type-inference algorithms are used that cannot backtrack and instead generate an error message in such a situation. This behavior may be preferable as type inference may not always be neutral algorithmically, as illustrated by the prior floating-point precision issue.

An algorithm of intermediate generality implicitly declares result2 as a floating-point variable, and the addition implicitly converts x to a floating point. This can be correct if the calling contexts never supply a floating point argument. Such a situation shows the difference between type inference, which does not involve type conversion, and implicit type conversion, which forces data to a different data type, often without restrictions.

Finally, a significant downside of complex type-inference algorithm is that the resulting type inference resolution is not going to be obvious to humans (notably because of the backtracking), which can be detrimental as code is primarily intended to be comprehensible to humans.

The recent emergence of just-in-time compilation allows for hybrid approaches where the type of arguments supplied by the various calling context is known at compile time, and can generate a large number of compiled versions of the same function. Each compiled version can then be optimized for a different set of types. For instance, JIT compilation allows there to be at least two compiled versions of add_one:

A version that accepts an integer input and uses implicit type conversion.
A version that accepts a floating-point number as input and uses floating point instructions throughout.

Technical description

[edit]

Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given. In many cases, it is possible to omit type annotations from a program completely if the type inference system is robust enough, or the program or language is simple enough.

To obtain the information required to infer the type of an expression, the compiler either gathers this information as an aggregate and subsequent reduction of the type annotations given for its subexpressions, or through an implicit understanding of the type of various atomic values (e.g. true : Bool; 42 : Integer; 3.14159 : Real; etc.). It is through recognition of the eventual reduction of expressions to implicitly typed atomic values that the compiler for a type inferring language is able to compile a program completely without type annotations.

In complex forms of higher-order programming and polymorphism, it is not always possible for the compiler to infer as much, and type annotations are occasionally necessary for disambiguation. For instance, type inference with polymorphic recursion is known to be undecidable. Furthermore, explicit type annotations can be used to optimize code by forcing the compiler to use a more specific (faster/smaller) type than it had inferred.[14]

Some methods for type inference are based on constraint satisfaction[15] or satisfiability modulo theories.[16]

High-Level Example

[edit]

As an example, the Haskell function map applies a function to each element of a list, and may be defined as:

map f [] = []
map f (first:rest) = f first : map f rest

(Recall that : in Haskell denotes cons, structuring a head element and a list tail into a bigger list or destructuring a nonempty list into its head element and its tail. It does not denote "of type" as in mathematics and elsewhere in this article; in Haskell that "of type" operator is written :: instead.)

Type inference on the map function proceeds as follows. map is a function of two arguments, so its type is constrained to be of the form a -> b -> c. In Haskell, the patterns [] and (first:rest) always match lists, so the second argument must be a list type: b = [d] for some type d. Its first argument f is applied to the argument first, which must have type d, corresponding with the type in the list argument, so f :: d -> e (:: means "is of type") for some type e. The return value of map f, finally, is a list of whatever f produces, so [e].

Putting the parts together leads to map :: (d -> e) -> [d] -> [e]. Nothing is special about the type variables, so it can be relabeled as

map :: (a -> b) -> [a] -> [b]

It turns out that this is also the most general type, since no further constraints apply. As the inferred type of map is parametrically polymorphic, the type of the arguments and results of f are not inferred, but left as type variables, and so map can be applied to functions and lists of various types, as long as the actual types match in each invocation.

Detailed Example

[edit]

The algorithms used by programs like compilers are equivalent to the informally structured reasoning above, but a bit more verbose and methodical. The exact details depend on the inference algorithm chosen (see the following section for the best-known algorithm), but the example below gives the general idea. We again begin with the definition of map:

map f [] = []
map f (first:rest) = f first : map f rest

(Again, remember that the : here is the Haskell list constructor, not the "of type" operator, which Haskell instead spells ::.)

First, we make fresh type variables for each individual term:

  • α shall denote the type of map that we want to infer.
  • β shall denote the type of f in the first equation.
  • [γ] shall denote the type of [] on the left side of the first equation.
  • [δ] shall denote the type of [] on the right side of the first equation.
  • ε shall denote the type of f in the second equation.
  • ζ -> [ζ] -> [ζ] shall denote the type of : on the left side of the first equation. (This pattern is known from its definition.)
  • η shall denote the type of first.
  • θ shall denote the type of rest.
  • ι -> [ι] -> [ι] shall denote the type of : on the right side of the first equation.

Then we make fresh type variables for subexpressions built from these terms, constraining the type of the function being invoked accordingly:

  • κ shall denote the type of map f []. We conclude that α ~ β -> [γ] -> κ where the "similar" symbol ~ means "unifies with"; we are saying that α, the type of map, must be compatible with the type of a function taking a β and a list of γs and returning a κ.
  • λ shall denote the type of (first:rest). We conclude that ζ -> [ζ] -> [ζ] ~ η -> θ -> λ.
  • μ shall denote the type of map f (first:rest). We conclude that α ~ ε -> λ -> μ.
  • ν shall denote the type of f first. We conclude that ε ~ η -> ν.
  • ξ shall denote the type of map f rest. We conclude that α ~ ε -> θ -> ξ.
  • ο shall denote the type of f first : map f rest. We conclude that ι -> [ι] -> [ι] ~ ν -> ξ -> ο.

We also constrain the left and right sides of each equation to unify with each other: κ ~ [δ] and μ ~ ο. Altogether the system of unifications to solve is:

α ~ β -> [γ] -> κ
ζ -> [ζ] -> [ζ] ~ η -> θ -> λ
α ~ ε -> λ -> μ
ε ~ η -> ν
α ~ ε -> θ -> ξ
ι -> [ι] -> [ι] ~ ν -> ξ -> ο
κ ~ [δ]
μ ~ ο

Then we substitute until no further variables can be eliminated. The exact order is immaterial; if the code type-checks, any order will lead to the same final form. Let us begin by substituting ο for μ and [δ] for κ:

α ~ β -> [γ] -> [δ]
ζ -> [ζ] -> [ζ] ~ η -> θ -> λ
α ~ ε -> λ -> ο
ε ~ η -> ν
α ~ ε -> θ -> ξ
ι -> [ι] -> [ι] ~ ν -> ξ -> ο

Substituting ζ for η, [ζ] for θ and λ, ι for ν, and [ι] for ξ and ο, all possible because a type constructor like · -> · is invertible in its arguments:

α ~ β -> [γ] -> [δ]
α ~ ε -> [ζ] -> [ι]
ε ~ ζ -> ι

Substituting ζ -> ι for ε and β -> [γ] -> [δ] for α, keeping the second constraint around so that we can recover α at the end:

α ~ (ζ -> ι) -> [ζ] -> [ι]
β -> [γ] -> [δ] ~ (ζ -> ι) -> [ζ] -> [ι]

And, finally, substituting (ζ -> ι) for β as well as ζ for γ and ι for δ because a type constructor like [·] is invertible eliminates all the variables specific to the second constraint:

α ~ (ζ -> ι) -> [ζ] -> [ι]

No more substitutions are possible, and relabeling gives us map :: (a -> b) -> [a] -> [b], the same as we found without going into these details.

Hindley–Milner type inference algorithm

[edit]

The algorithm first used to perform type inference is now informally termed the Hindley–Milner algorithm, although the algorithm should properly be attributed to Damas and Milner.[17] It is also traditionally called type reconstruction.[1]:?320? If a term is well-typed in accordance with Hindley–Milner typing rules, then the rules generate a principal typing for the term. The process of discovering this principal typing is the process of "reconstruction".

The origin of this algorithm is the type inference algorithm for the simply typed lambda calculus that was devised by Haskell Curry and Robert Feys in 1958.[citation needed] In 1969 J. Roger Hindley extended this work and proved that their algorithm always inferred the most general type. In 1978 Robin Milner,[18] independently of Hindley's work, provided an equivalent algorithm, Algorithm W. In 1982 Luis Damas[17] finally proved that Milner's algorithm is complete and extended it to support systems with polymorphic references.

Side-effects of using the most general type

[edit]

By design, type inference will infer the most general type appropriate. However, many languages, especially older programming languages, have slightly unsound type systems, where using a more general types may not always be algorithmically neutral. Typical cases include:

  • Floating-point types being considered as generalizations of integer types. Actually, floating-point arithmetic has different precision and wrapping issues than integers do.
  • Variant/dynamic types being considered as generalizations of other types in cases where this affects the selection of operator overloads. For example, the + operator may add integers but may concatenate variants as strings, even if those variants hold integers.

Type inference for natural languages

[edit]

Type inference algorithms have been used to analyze natural languages as well as programming languages.[19][20][21] Type inference algorithms are also used in some grammar induction[22][23] and constraint-based grammar systems for natural languages.[24]

References

[edit]
  1. ^ a b Benjamin C. Pierce (2002). Types and Programming Languages. MIT Press. ISBN 978-0-262-16209-8.
  2. ^ "WG14-N3007 : Type inference for object definitions". open-std.org. 2025-08-07. Archived from the original on December 24, 2022.
  3. ^ "Placeholder type specifiers (since C++11) - cppreference.com". en.cppreference.com. Retrieved 2025-08-07.
  4. ^ "The Dart type system". dart.dev. Retrieved 2025-08-07.
  5. ^ cartermp. "Type Inference - F#". docs.microsoft.com. Retrieved 2025-08-07.
  6. ^ "Inference · The Julia Language". docs.julialang.org. Retrieved 2025-08-07.
  7. ^ "Kotlin language specification". kotlinlang.org. Retrieved 2025-08-07.
  8. ^ "Statements - The Rust Reference". doc.rust-lang.org. Retrieved 2025-08-07.
  9. ^ "Type Inference". Scala Documentation. Retrieved 2025-08-07.
  10. ^ "The Basics — The Swift Programming Language (Swift 5.5)". docs.swift.org. Retrieved 2025-08-07.
  11. ^ "Documentation - Type Inference". www.typescriptlang.org. Retrieved 2025-08-07.
  12. ^ "Projects/Vala/Tutorial - GNOME Wiki!". wiki.gnome.org. Retrieved 2025-08-07.
  13. ^ KathleenDollard. "Local Type Inference - Visual Basic". docs.microsoft.com. Retrieved 2025-08-07.
  14. ^ Bryan O'Sullivan; Don Stewart; John Goerzen (2008). "Chapter 25. Profiling and optimization". Real World Haskell. O'Reilly.
  15. ^ Talpin, Jean-Pierre, and Pierre Jouvelot. "Polymorphic type, region and effect inference." Journal of functional programming 2.3 (1992): 245-271.
  16. ^ Hassan, Mostafa; Urban, Caterina; Eilers, Marco; Müller, Peter (2018). "MaxSMT-Based Type Inference for Python 3". Computer Aided Verification. Lecture Notes in Computer Science. Vol. 10982. pp. 12–19. doi:10.1007/978-3-319-96142-2_2. ISBN 978-3-319-96141-5.
  17. ^ a b Damas, Luis; Milner, Robin (1982), "Principal type-schemes for functional programs", POPL '82: Proceedings of the 9th ACM SIGPLAN-SIGACT symposium on principles of programming languages (PDF), ACM, pp. 207–212
  18. ^ Milner, Robin (1978), "A Theory of Type Polymorphism in Programming", Journal of Computer and System Sciences, 17 (3): 348–375, doi:10.1016/0022-0000(78)90014-4, hdl:20.500.11820/d16745d7-f113-44f0-a7a3-687c2b709f66
  19. ^ Center, Artificia? Intelligence. Parsing and type inference for natural and computer languages Archived 2025-08-07 at the Wayback Machine. Diss. Stanford University, 1989.
  20. ^ Emele, Martin C., and Rémi Zajac. "Typed unification grammars Archived 2025-08-07 at the Wayback Machine." Proceedings of the 13th conference on Computational linguistics-Volume 3. Association for Computational Linguistics, 1990.
  21. ^ Pareschi, Remo. "Type-driven natural language analysis." (1988).
  22. ^ Fisher, Kathleen, et al. "Fisher, Kathleen, et al. "From dirt to shovels: fully automatic tool generation from ad hoc data." ACM SIGPLAN Notices. Vol. 43. No. 1. ACM, 2008." ACM SIGPLAN Notices. Vol. 43. No. 1. ACM, 2008.
  23. ^ Lappin, Shalom; Shieber, Stuart M. (2007). "Machine learning theory and practice as a source of insight into universal grammar" (PDF). Journal of Linguistics. 43 (2): 393–427. doi:10.1017/s0022226707004628. S2CID 215762538.
  24. ^ Stuart M. Shieber (1992). Constraint-based Grammar Formalisms: Parsing and Type Inference for Natural and Computer Languages. MIT Press. ISBN 978-0-262-19324-5.
[edit]
吃饭时头晕是什么原因 无犯罪记录证明需要什么材料 吃维生素b12有什么好处和副作用 胃泌素17是什么检查 乙肝携带者是什么意思
磨牙是什么原因怎么治疗 灰什么丧什么 为什么会长口腔溃疡的原因 吃头孢不能吃什么 歧路亡羊告诉我们什么道理
大腿抽筋是什么原因 体毛多是什么原因 糖尿病吃什么水果最好 kt是什么意思 河南属于什么平原
有什么好看的国漫 一直吐是什么原因 一年半载是什么意思 服中药期间忌吃什么 坐月子什么不可以吃
手术后吃什么水果hcv8jop5ns9r.cn 尿蛋白微量是什么意思hcv9jop3ns4r.cn 鸡炖什么好吃又有营养hcv8jop6ns7r.cn 悲智双运什么意思hcv9jop0ns0r.cn 蛋白糖是什么糖hcv8jop4ns3r.cn
阳历三月是什么星座hcv7jop4ns7r.cn aqua是什么牌子hcv8jop8ns7r.cn 孕早期胎停有什么症状或征兆吗zhongyiyatai.com 唐氏综合征是什么意思hcv8jop2ns6r.cn 尿频尿急尿不尽吃什么药效果最好hcv8jop5ns9r.cn
绿豆可以和什么一起煮hcv8jop1ns4r.cn 什么是二级医院0735v.com 萤火虫为什么会发光简单回答hcv9jop4ns1r.cn 上腹部饱胀是什么原因hcv9jop1ns8r.cn 脐炎用什么药hcv8jop3ns4r.cn
吃完饭就打嗝是什么原因hcv8jop9ns3r.cn 尿酸看什么科jingluanji.com 手抖是什么病的前兆hcv9jop3ns4r.cn 包二奶什么意思hcv8jop1ns8r.cn 腔梗是什么病hcv8jop1ns0r.cn
百度