汇总行的更好方法

时间:2018-11-02 06:20:20

标签: f# refactoring sequence

我正在(再次)学习F#,并且试图对excel中的某些行求和。这是我的尝试。

let sumRows (source: seq<double[]>) =
    source
    |> Seq.reduce (fun a b -> (a, b) ||> Seq.map2 (fun x y -> x + y) |> Seq.toArray)

可以做得更好吗?我已经发现了双前向管道运算符,但是现在,fun a b -> (a, b) ||>的整个部分似乎很多余...

1 个答案:

答案 0 :(得分:5)

是的,这是多余的,因为双管道运算符仅在需要将元组转换为两个单独的参数时才方便。在这种情况下,您已经将它们作为2个单独的参数,因此可以像这样传递它们:

let sumRows (source: seq<double[]>) =
    source
    |> Seq.reduce (fun a b -> Seq.map2 (fun x y -> x + y) a b |> Seq.toArray)

我们可以通过将|> Seq.toArray替换为Seq.map2来摆脱Array.map2

let sumRows (source: seq<double[]>) =
    source
    |> Seq.reduce (fun a b -> Array.map2 (fun x y -> x + y) a b)

现在我们可以通过删除fun a b ->来进一步简化:

let sumRows (source: seq<double[]>) =
    source
    |> Seq.reduce (Array.map2 (fun x y -> x + y) )

最后,您是否知道像+这样的运算符可以视为2参数函数 加上括号(+)

let sumRows2 (source: seq<double[]>) =
    source
    |> Seq.reduce (Array.map2 (+) )

所有这些版本都具有相同的签名,并且都是正确的。您可以选择更适合自己风格的方式。

顺便说一句,您可能想进一步尝试一下:

let sumRows2 = Seq.reduce (Array.map2 (+) )

但是会导致著名的Value restriction错误。有一些变通办法,例如添加类型注释或在代码中的某个地方实际使用它,但是最好的变通办法是像以前一样添加参数。