以下的观察(那种惊讶我的)一个小例子:局部解构(F#)
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,答案永远是
型矢量= INT * INT
鉴于这些观察,得出的结论是“int * int”和“(int * int)”表示完全相同的类型和t在任何一段代码中的所有事件都可以用另一段代替(参考文献1)。透明度)......正如我们所看到的,这不是真的。
此外,为了解释手边的行为,我们不得不求助于谈论“编译后的代码如何”,而不是语言的语义属性,而这些语义属性表示存在一些“语言语义之间的紧张关系和编译器实际做的事情。
试着用'type Vector = V(float * float)'来代替编译器为内容使用一个实际的元组。 – kvb
它的工作原理! ...但它怎么会有所作为...我的意思是 类型Vector =(浮点数V)* float甚至不会有效? –
问题是:x * y'的V是否意味着“V拥有x和y类型的元组的元组”或者“V拥有x和y两个不同的字段”?如果你不加括号,那么编译器会假设后者,但是如果你用括号括起来,它意味着前者。这种区别主要与其他.NET语言的互操作性有关,但正如您发现的,它也会影响在某些情况下如何与F#中的此类类型的值进行交互。 – kvb