如何在F#中将本质上是元组的类型视为元组进行处理

4

好的,假设我有一个这样定义的类型:

type Foo = 
    | Bar of (SomeType * SomeType * SomeType * SomeType)
    | ...(other defs)

我有一个Bar,它基本上是由4个SomeTypes组成的元组。我想访问元组中的单个成员。我尝试了这个:

let Bar (one, two, three, four) = someBar

但是当我后来尝试引用one或two时,它会说“值或构造函数未定义”,所以它没有按预期处理赋值。正确的做法是什么?

另外,如果我尝试:

let one,two,three,four = someBar

它报错了:

someBar应该是'a*'b*'c*'d类型,但这里的类型是Foo

谢谢。

2个回答

6
您只需要再添加一组括号即可:
let (Bar(one,two,three,four)) = someBar

正如Stephen所指出的,如果没有额外的括号,编译器会将这行代码视为定义一个名为Bar的新函数。他也正确地指出,如果联合类型中有其他情况,模式匹配可能更合适。

啊!当我第一次看到这个时,添加括号在我的脑海中浮现,但我没有走那条路! - Stephen Swensen

1

给定

type Foo = 
    | Bar of (int * int * int * int)
    | Bar2 of string

let x = Bar(1,2,3,4)

let Bar(y1,y2,y3,y4) = x

最后一个 let 绑定被解释为一个函数,Bar : 'a * 'b * 'c * 'd -> Foo。函数名字让你有些困惑,因为它和 union case 相同,但实际上与你定义的 let some_func_takes_a_tuple_and_returns_x (y1,y2,y3,y4) = x 是一样的。

我觉得你可能需要多说一点:

let y1,y2,y3,y4 =
    match x with
    | Bar(y1,y2,y3,y4) -> y1,y2,y3,y4

这是很公平的,因为与元组分解的绑定不同,这里对Bar进行分解是危险的,因为匹配是不完整的(x实际上可能是其他Foo情况,比如Bar2)。

编辑

@kvb知道如何使这个工作符合您的期望!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接