Есть ли в OCaml оператор композиции инфиксных функций?

Просто быстрый вопрос. Мне интересно, есть ли в OCaml оператор композиции инфиксных функций, определенный в стандартной библиотеке (или в ядре Джейн Стрит, или в Батареях), такой как функция (.) В Haskell, которая экономит нам много скобок, так как мы можем написать (f . g . h) x вместо менее привлекательного f (g (h x))),

Спасибо, ребята.

6 ответов

Решение

Ответ здесь такой же, как и для flip:-). Состав функций не определен в стандартной библиотеке OCaml. В данном случае я не скучаю по этому время от времени, я скучаю по нему все время.

Проект OCaml Batteries Included определяет состав функции (в том порядке, в котором вы ее задаете) с помощью оператора -| в BatStd модуль. Как указывает Лукстафи (см. Ниже), этот оператор, по-видимому, изменится на % в будущем выпуске батарей. (Я подтвердил это в их исходном дереве.)

Насколько я вижу, проект Jane Street Core не определяет оператор композиции функций. Определяет функцию compose в Fn модуль.

Я просто хочу добавить, что оператор довольно легко включить, в 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))

Есть Fn.compose функция в ядре, но это не инфиксный оператор. Кроме того, он реализован как обычная функция и имеет накладные расходы времени выполнения.

На практике довольно удобно использовать трубочный оператор. Он не имеет накладных расходов времени выполнения, реализованных непосредственно в компиляторе (начиная с 4.00). См. Оптимизированные операторы труб для более подробной информации.

Оператор трубы доступен как '|>' в Core. Итак, вы можете переписать ваше выражение следующим образом: h x |> g |> f

Использование инфиксного оператора композиции, похоже, не рекомендуется. (см. это обсуждение).

Ты можешь написать f @@ g @@ h x вместо f (g (h x))),

В контейнерах (еще одна замена 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]

Может быть, это может помочь вам.

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
Другие вопросы по тегам