When we wrote map, we transformed each element of the list. What if we wanted to compile all the elements of a list together? We could sum or concatenate all the elements in a list:
let rec sum = function
| [] -> 0
| h :: t -> h + sum t;;
let rec concat = function
| [] -> ""
| h :: t -> h ^ concat t;;
val sum : int list -> int = <fun>
val concat : string list -> string = <fun>
let ints = [1110; 2110; 2800; 3110];;
let strings = ["python"; "oop"; "discrete"; "functional"]
val ints : int list = [1110; 2110; 2800; 3110]
val strings : string list = ["python"; "oop"; "discrete"; "functional"]
sum ints;;
concat strings;;
- : int = 9130
- : string = "pythonoopdiscretefunctional"
Now we have a bunch of repeated code! Let's extract the repeated code into a function!
let rec combine init op = function
| [] -> init
| h :: t -> op h (combine init op t);;
val combine : 'a -> ('b -> 'a -> 'a) -> 'b list -> 'a = <fun>
Now let's rewrite sum and concat in terms of combine.
let sum' = combine 0 ( + );;
let concat' = combine "" ( ^ );;
val sum' : int list -> int = <fun>
val concat' : string list -> string = <fun>
sum ints;;
concat strings;;
- : int = 9130
- : string = "pythonoopdiscretefunctional"
Now we've factored out all the common code!
The code that we just wrote is very similar to an OCaml standard library function family called fold.