Two useful higher-order functions are the binary application (@@
) and reverse-application or "pipe" (|>
) operators. Although since 4.01 they're available as primitives, it might still be instructive to define them here:
let (|>) x f = f x
let (@@) f x = f x
Consider the problem of incrementing the square of 3. One way of expressing that computation is this:
(* 1 -- Using parentheses *)
succ (square 3)
(* - : int = 10 *)
(* where `square` is defined as: *)
let square x = x * x
Note that we couldn't simply do succ square 3
because (due to left-associativity) that would reduce to the meaningless (succ square) 3
. Using application (@@
) we can express that without the parentheses:
(* 2 -- Using the application operator *)
succ @@ square 3
(* - : int = 10 *)
Notice how the last operation to be performed (namely succ
) occurs first in the expression? The reverse-application operator (|>
) allows us to, well, reverse this:
(* 3 -- Using the reverse-application operator *)
3 |> square |> succ
(* - : int = 10 *)
The number 3 is now "piped" through square
and then succ
, as opposed to being applied to square
to yield a result that succ
is applied to.