我怎样才能将一个基本上是元组的类型视为F#中的元组

时间:2011-03-10 02:09:10

标签: syntax f# types tuples

好的,我们假设我的类型定义如下:

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

所以我有一个Bar,它基本上是4个SomeTypes的元组。我想访问元组的各个成员。我试过这个:

让Bar(一,二,三,四)= someBar

但是当我尝试在函数中引用一个或两个时,它表示“值或构造函数未定义”因此它不按预期处理赋值。这样做的正确方法是什么?

另外,如果我尝试:

let one,two,three,four = someBar

抱怨: someBar预计会有'a *'b *'c *'d类型,但这里有类型Foo

感谢,

2 个答案:

答案 0 :(得分:6)

您只需要添加另一组括号:

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

正如Stephen所指出的那样,如果没有额外的parens,编译器会将这行代码视为一个名为Bar的新函数的定义。如果在受歧视的联盟中存在其他案例,那么模式匹配可能更合适也是对的。

答案 1 :(得分: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。函数名称会让你失望,因为它与你的联合案例相同,但它与定义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情况,如{{ 1}})。

修改

@kvb知道让你按预期工作的秘诀!