Лучший способ суммировать строки - PullRequest
0 голосов
/ 02 ноября 2018

Я изучаю 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 голосов
/ 02 ноября 2018

Вы правы, это избыточно, потому что оператор двойной трубы удобен только тогда, когда вам нужно преобразовать кортеж в два отдельных параметра. В этом случае у вас уже есть два отдельных параметра, поэтому вы можете просто передать их так:

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) )

Наконец, знаете ли вы, что такой оператор, как +, можно рассматривать как функцию с двумя параметрами поставив в скобках (+)?

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

Все эти версии имеют одинаковую подпись, и все они верны. Вы выбираете тот, который больше подходит вашему стилю.

Кстати, у вас может возникнуть желание пойти еще дальше и сделать это:

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

но это вызывает проблемы со знаменитой ошибкой Value restriction. Есть обходные пути, такие как добавление аннотации типа или фактически использование ее где-то в коде, но лучший обходной путь - это добавление параметра, как мы делали раньше.

...