Recall that functions are values.
This is called higher order functions
let double x = 2 * x;;
let square x = x * x;;
val double : int -> int = <fun>
val square : int -> int = <fun>
Now we have two functions, but what if we wanted to quadruple a function?
let quad1 x = 4 * x;;
val quad1 : int -> int = <fun>
Sure that works, but there are other ways of writing this function!
let quad2 x = double (double x);;
val quad2 : int -> int = <fun>
Now we're doubling x twice. We can do the same thing with the pipeline operator.
let quad3 x = x |> double |> double;;
val quad3 : int -> int = <fun>
Just to clarify, these are all the same!
quad1 6;;
quad2 6;;
quad3 6;;
- : int = 24
- : int = 24
- : int = 24
What if we wanted to raise a number to the fourth? Once again, we can do this a few ways:
let fourth1 x = x * x * x * x;;
let fourth2 x = square (square x);;
let fourth3 x = x |> square |> square;;
val fourth1 : int -> int = <fun>
val fourth2 : int -> int = <fun>
val fourth3 : int -> int = <fun>
Again, these all do the same thing
fourth1 2;;
fourth2 2;;
fourth3 2;;
- : int = 16
- : int = 16
- : int = 16
Notice that in fourth and quad, we're applying a function twice. Let's generalize this in a function twice. This just applies a function twice!
let twice f x = x |> f |> f;;
val twice : ('a -> 'a) -> 'a -> 'a = <fun>
Note the type of twice is ('a -> 'a) -> 'a -> 'a. The ('a -> 'a) is a function that takes in an 'a and returns an 'a. Let's rewrite our quad and fourth functions to use this new twice function.
let quad4 x = twice double x;;
let fourth4 x = twice square x;;
val quad4 : int -> int = <fun>
val fourth4 : int -> int = <fun>
And once again, to show that these work:
quad4 6;;
fourth4 2;;
- : int = 24
- : int = 16
We can actually make this more concise! We can drop the parameter:
let quad5 = twice double;;
let fourth5 = twice square;;
val quad5 : int -> int = <fun>
val fourth5 : int -> int = <fun>
quad5 6;;
fourth5 2;;
- : int = 24
- : int = 16
These functions do a partial application, then return the function as a result.