【问题标题】:Squashing tuples from (a,(b,c)) to (a,b,c) in fsharp在 fsharp 中将元组从 (a,(b,c)) 压缩到 (a,b,c)
【发布时间】:2012-03-02 09:41:19
【问题描述】:

定义这样的函数有意义吗

let squash12 (e:('a*('b*'c)   )) = e |> (fun (a,(b,c)  ) -> (a,b,c  ))
let squash21 (e:(('a*'b)*'c   )) = e |> (fun ((a,b),c  ) -> (a,b,c  ))
let squash13 (e:('a*('b*'c*'d))) = e |> (fun (a,(b,c,d)) -> (a,b,c,d))

let seqsquash12 (sa:seq<'T>) = sa |> Seq.map squash12
let seqsquash21 (sa:seq<'T>) = sa |> Seq.map squash21
let seqsquash13 (sa:seq<'T>) = sa |> Seq.map squash13

我找不到另一种方法来使我的核心代码递归(导致嵌套元组),同时公开映射到广义 n 维坐标的简单函数。

【问题讨论】:

    标签: f# tuples inline iterable-unpacking


    【解决方案1】:

    我会将您的函数标记为内联,以便它们可以是

    let inline squash1 (a,(b,c)) = (a,b,c)
    

    另外,你不需要 lambdas (fun ...)

    【讨论】:

    • 谢谢。我注意到类型推断很慢(我只对基本函数使用更高阶的东西),所以如果它加快速度,我不妨指定类型。
    • @nicolas - 真的,我不认为类型推断很慢 + 这个版本在运行时会快得多(避免函数调用)
    • @nicolas:请参阅我的回答以获取一般情况下的建议。
    【解决方案2】:

    是的,这样做很有意义。建议避免使用 lambda 以使这些函数更易于阅读:

    let squash12 (a, (b, c)) = a, b, c
    

    如果您经常遇到具有不同数量的内部元组,将它们转换为列表不是一个坏主意。例如,e 成为两个列表的元组:

    (a, (b, c)) ~> ([a], [b; c])
    (a, b), c) ~> ([a; b], [c])
    (a, (b, c, d)) ~> (a, [b; c; d])
    

    我们只需要一个函数来处理序列:

    let seqsquash sa = sa |> Seq.map (@)
    

    问题是你失去了对输入大小的控制。列表上的模式匹配可能会有所帮助:

    let squash12 (xs, ys) = 
       match xs, ys with
       | [a], [b; c] -> xs, ys
       | _ -> failwith "Wrong input size"
    

    【讨论】:

      猜你喜欢
      • 2011-05-30
      • 2011-08-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      相关资源
      最近更新 更多