gpt4 book ai didi

f# - 记录类型推断

转载 作者:行者123 更新时间:2023-12-04 05:18:51 25 4
gpt4 key购买 nike

在以下代码段中

type myrec1 = {x: int; y: int}
type myrec2 = {x: int; y: int; z: int}

let p1 = {x = 1; y = 1} // Error. p1 compiler assumes p1 has the type myrec2

// It works with additional type specification
let p1: myrec1 = {x = 1; y = 1}
let p2: myrec2 = {x = 1; y = 1; z = 1}

带有注释的行不会编译。由于某种原因,类型检查器无法确定p1的类型应为myrec1。是因为这种类型推断的情况根本无法解决,还是仅仅是F#类型推断的局限性?

最佳答案

here:

The labels of the most recently declared type take precedence over those of the previously declared type



因此,如果您这样做:
type myrec2 = {x: int; y: int; z: int}
type myrec1 = {x: int; y: int}

let p1 = {x = 1; y = 1}

那么它将起作用。

为了使您从 here(F#3.0规范)中获得阅读乐趣:
field-initializer : long-ident = expr

6.3.5记录表达式

在这种情况下,我们的字段初始化器不是单个标识符,因此它使用14.1.9中的“字段标签解析”。

Each field-initializeri has the form field-labeli = expri. Each field-labeli is a long-ident, which must resolve to a field Fi in a unique record type R as follows:

·         If field-labeli is a single identifier fld and the initial type is known to be a record type R<,...,> that has field Fi with name fld, then the field label resolves to Fi.

·         If field-labeli is not a single identifier or if the initial type is a variable type, then the field label is resolved by performing Field Label Resolution (see §14.1) on field-labeli. This procedure results in a set of fields FSeti. Each element of this set has a corresponding record type, thus resulting in a set of record types RSeti. The intersection of all RSeti must yield a single record type R, and each field then resolves to the corresponding field in R.



14.1.9字段标签分辨率

我们的长期身份是FieldLabel,因此使用8.4.2中描述的FieldLabels表进行查找。

Field Label Resolution specifies how to resolve identifiers such as field1 in { field1 = expr; ... fieldN = expr }. Field Label Resolution proceeds through the following steps:

1.     Look up all fields in all available types in the Types table and the FieldLabels table (§8.4.2).

2.     Return the set of field declarations.



8.4.2名称解析和记录字段标签

如此处所述,FieldLabels表用于成员的名称解析(14.1)。

For a record type, the record field labels field1 ... fieldN are added to the FieldLabels table of the current name resolution environment unless the record type has the RequireQualifiedAccess attribute. Record field labels in the FieldLabels table play a special role in Name Resolution for Members (§14.1): an expression’s type may be inferred from a record label. For example: type R = { dx : int; dy: int } let f x = x.dx // x is inferred to have type R In this example, the lookup .dx is resolved to be a field lookup.



14.1.4表达式中的名称解析
本节似乎有些模糊,但是我认为这时使用了名称解析。如最后所述,如果有多个项,则返回第一项。

Given an input long-ident, environment env, and an optional count n of the number of subsequent type arguments <,...,>, Name Resolution in Expressions computes a result that contains the interpretation of the long-ident<,...,> prefix as a value or other expression item, and a residue path rest. How Name Resolution in Expressions proceeds depends on whether long-ident is a single identifier or is composed of more than one identifier. If long-ident is a single identifier ident:

1.     Look up ident in the ExprItems table. Return the result and empty rest.

2.     If ident does not appear in the ExprItems table, look it up in the Types table, with generic arity that matches n if available. Return this type and empty rest.

3.     If ident does not appear in either the ExprItems table or the Types table, fail.

...

If the expression contains ambiguities, Name Resolution in Expressions returns the first result that the process generates.



您感兴趣的部分是上面的最后一行:“返回过程生成的第一个结果”。

关于f# - 记录类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15812608/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com