Мне кажется, что все это связано. В чем разница?
Трубопроводы, композиция и каррирование
Ответ 1
-
Трубопровод используется для выполнения последовательности операций с некоторым значением (точно так же, как трубопроводы в Unix). Вход для каждой функции - это выход предыдущей функции. Очевидно, это требует, чтобы каждая функция принимала один аргумент.
-
Композиция (
<<
/>>
) похожа на то, что она вызывает две функции в последовательности (т.е. вывод первого - это вход ко второму), но он возвращает функцию вместо непосредственного вызова последовательность. -
Currying создает новую функцию, применяя аргументы 1 к N-1 для функции N args
Итак, композиция и currying используются для создания функций, тогда как для вызова используется конвейер. Состав и карри отличаются друг от друга тем, как они создают новые функции (применяя args vs chaining).
Ответ 2
В дополнение к тому, что написал Даниил, существует очень тесное соответствие между трубопроводами (операторами |>
и <|
) и композицией функций (операторы >>
и <<
).
Когда вы используете конвейер для передачи некоторых данных в последовательность функций:
nums |> Seq.filter isOdd
|> Seq.map square
|> Seq.sum
... то это эквивалентно передаче ввода функции, полученной с использованием композиции функций:
let composed =
Seq.filter isOdd
>> Seq.map square
>> Seq.sum
composed nums
На практике это часто означает, что вы можете заменить объявление функции, которое использует конвейер в аргументе с составом функций (и использовать тот факт, что функции могут использоваться как значения). Вот пример:
// Explicit function declaration
foo (fun x -> x |> bar |> goo)
// Equivalent using function composition
foo (bar >> goo)