【问题标题】:How can I treat a type that is essentially a tuple as a tuple in F#如何将本质上是元组的类型视为 F# 中的元组
【发布时间】:2011-03-10 02:09:10
【问题描述】:

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

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

谢谢,

【问题讨论】:

    标签: syntax f# types tuples


    【解决方案1】:

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

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

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

    【讨论】:

    • 啊!当我第一次看到这个时,我的脑海中闪过添加括号,但我没有走那条路!
    【解决方案2】:

    给定

    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
    

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

    编辑

    @kvb 知道让这项工作如您所愿的秘诀!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 2020-04-11
      • 1970-01-01
      • 1970-01-01
      • 2016-05-25
      • 2020-06-04
      • 1970-01-01
      相关资源
      最近更新 更多