gpt4 book ai didi

constructor - 模式匹配中的部分解构 (F#)

转载 作者:行者123 更新时间:2023-12-04 21:36:26 25 4
gpt4 key购买 nike

遵循观察的最小示例(这让我感到惊讶):

type Vector = V of float*float

// complete unfolding of type is OK
let projX (V (a,_)) = a

// also works
let projX' x =
match x with
| V (a, _) -> a

// BUT:
// partial unfolding is not Ok
let projX'' (V x) = fst x

// consequently also doesn't work
let projX''' x =
match x with
| V y -> fst y

导致无法匹配部分解构类型的原因是什么?

一些部分解构似乎没问题:
// Works
let f (x,y) = fst y

编辑:
好的,我现在了解所描述行为的“技术”原因(感谢您的回答和评论)。但是,我认为语言明智,与其他语言相比,这种行为感觉有点“不自然”:

“代数”,对我来说,将类型“t”与类型“(t)”区分开来似乎很奇怪。括号(在这种情况下)用于提供优先级,例如在“(t * s)* r”与“t *(s * r)”中。 fsi 也相应地回答,我是否发送
type Vector = (int * int)

或者
type Vector = int * int

对于 fsi,答案总是

type Vector = int * int



鉴于这些观察,人们得出结论,“int * int”和“(int * int)”表示完全相同的类型,因此在任何一段代码中所有出现的一个都可以替换为另一个(引用透明度)。 . 正如我们所见,这不是真的。

此外,为了解释手头的行为,我们不得不谈论“一些代码编译后的样子”而不是语言的语义属性,这似乎很重要,imo 表明语言之间存在一些“张力”语义是编译器实际执行的操作。

最佳答案

在 F#

type Vector = V of float*float

只是一个退化的联合(你可以通过在 Visual Studio 中悬停它来看到),所以它等价于:
type Vector = 
| V of float*float
of之后的部分创建两个 anonymous field s(如 F# 引用中所述)和一个接受两个 float 类型参数的构造函数。

如果你定义
type Vector2 = 
| V2 of (float*float)

只有一个匿名字段是一个浮点元组和一个带有单个参数的构造函数。正如评论中指出的那样,您可以使用 Vector2进行所需的模式匹配。

毕竟,以下代码有效似乎不合逻辑:
let argsTuple = (1., 1.)
let v1 = V argsTuple

但是,如果您考虑到存在隐藏模式匹配,则一切都应该很清楚。

编辑:

F# language spec (p 122)明确指出括号在联合定义中很重要:

Parentheses are significant in union definitions. Thus, the following two definitions differ:

type CType = C of int * int

type CType = C of (int * int)

The lack of parentheses in the first example indicates that the union case takes two arguments. The parentheses in the second example indicate that the union case takes one argument that is a first-class tuple value.



我认为这种行为与您可以在联合的定义中定义更复杂的模式的事实一致,例如:
    type Move = 
| M of (int * int) * (int * int)

能够使用具有多个参数的 union 也很有意义,尤其是在互操作情况下,当使用元组很麻烦时。

你使用的另一件事:
type Vector = int * int

type abbreviation它只是为某种类型命名。将括号放在 int * int 周围没有区别,因为这些括号将被视为分组括号。

关于constructor - 模式匹配中的部分解构 (F#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36507116/

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