Есть ли в OCaml оператор композиции функции infix?
Просто быстрый вопрос. Мне интересно, если в OCaml, определенном в стандартной библиотеке (или в Jane Street Core или в Batteries), есть оператор настройки функции infix, как функция (.) В Haskell, которая экономит нам много круглых скобок, так как мы можем написать (f . g . h) x
вместо менее привлекательного f (g (h x)))
.
Спасибо, ребята.
Ответы
Ответ 1
Ответ здесь такой же, как и для flip
:-). Состав функций не определен в стандартной библиотеке OCaml. В этом случае я не пропущу время от времени, я все время скучаю по нему.
OCaml Batteries Included проект определяет состав функции (в указанном порядке) с помощью оператора -|
в BatStd
. Как указывает lukstafi (см. Ниже), этот оператор, по-видимому, изменится на %
в будущей версии батарей. (Я проверил это в своем исходном дереве.)
Насколько я вижу, проект Jane Street Core не определяет оператора компоновки функций. Он определяет функцию compose
в модуле Fn
.
Ответ 2
В Core есть функция Fn.compose
, но это не инфиксный оператор. Кроме того, он реализуется как регулярная функция и имеет служебные данные времени выполнения.
На практике довольно удобно использовать оператор трубы. Он не имеет избыточных затрат времени исполнения, реализованных непосредственно в компиляторе (начиная с 4.00). Подробнее см. Оптимизированные операторы труб.
Оператор труб доступен как "| > " в Core. Итак, вы можете переписать свое выражение следующим образом: h x |> g |> f
Ответ 3
Я просто хочу добавить, что оператор довольно легко включить, в F # он просто определяется как:
let (<<) f g x = f(g(x));;
который имеет подпись типа: val ( << ) : f:('a -> 'b) -> g:('c -> 'a) -> x:'c -> 'b
делает именно то, что вам нужно...
(f << g << h) x = f(g(h(x))
поэтому вам не нужен проект батарей, если вам не нужно
Я хотел бы добавить, что причина, по которой это выглядит как <<
, как вы могли догадаться, потому что оператор >>
делает обратное:
let (>>) f g x = g(f(x));;
(f >> g >> h) x = h(g(f(x))
Ответ 4
Использование оператора инфиксной композиции кажется обескураженным. (см. это обсуждение).
Вы можете написать f @@ g @@ h x
вместо f (g (h x)))
.
Ответ 5
В Containers (еще одна замена stdlib для Ocaml), оператор композиции функции называется %
и может быть найден в CCFun модуль:
open Containers
open Fun
let is_zero n = (n = 0)
let nonzeros = List.filter (not % is_zero) [0;1;2;3;0]
Ответ 6
Может быть, это может вам помочь.
let identite f = f
let (>>) = List.fold_right identite
Тест:
# let f=fun x-> x+1 and
g=fun x-> x*2 and
h=fun x-> x+3;;
# [f;g;h] >> 2;;
- : int = 11