我正在(再次)学习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) ||>
的整个部分似乎很多余...
答案 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
错误。有一些变通办法,例如添加类型注释或在代码中的某个地方实际使用它,但是最好的变通办法是像以前一样添加参数。