假设我有以下(基本的,略显无意义的)F#...
type Point = Point of int * int
type MyUnion =
| MyInt of int
| MyString of string
| MyTwoStrings of string * string
| MyPoint of Point
...然后我可以写一个这样的函数......
let MyUnionType myunion =
match myunion with
| MyInt n -> printfn "You gave me an Int (%d)" n
| MyString s -> printfn "You gave me a string (%s)" s
| MyTwoStrings (s1, s2) -> printfn "You gave me two strings (\"%s\", \"%s\")" s1 s2
// Missing case here...
这适用于MyUnionType
的前三个版本,但我无法在MyPoint
我尝试了以下内容,类似于MyTwoStrings
案例......
| MyPoint (p1, p2) -> printfn "You gave me a point (%d, %d)" p1 p2
...但是这会产生编译错误,指出(p1, p2)
预计会有Point
类型,但类型为'a * 'b
我尝试了以下内容......
| MyPoint p -> printfn "You gave me a point (%A)" p
..哪有效,但无法让我访问int
Point
值
如何获取int
中的两个Point
值?
答案 0 :(得分:8)
type Point = Point of int * int
是一个单一案例的歧视联盟,而不仅仅是一个元组。
你构建它像let p = Point(0, 0)
,所以你需要以类似的方式解构它。您的上一个示例是一个很好的起点:| MyPoint p -> ...
将Point
值绑定到p
,以便稍后解构它:
| MyPoint p ->
let (Point (p1, p2)) = p
printfn "You gave me a point (%i, %i)" p1 p2
或者你可以在match
本身中结合解构:
| MyPoint (Point (p1, p2)) -> printfn "You gave me a point (%i, %i)" p1 p2
答案 1 :(得分:5)
您的类型$CLOUDSDK_PYTHON
与您的类型Point
具有完全相同的性质。唯一的区别是MyUnion
有一个构造函数,但Point
有几个。就是这样。
MyUnion
的构造函数与类型本身具有相同的名称这一事实完全无关紧要。类型名称和构造函数名称位于不同的名称空间中。它们可以相同也可以不同,不会改变任何东西。
因此,获取Point
类型内容的方式与Point
完全相同,例如:
MyUnion
然后,这种模式也可以嵌套在另一种模式中:
let sumCoords p = match p with
| Point (x,y) = x + y