## List functions

Some common iterative program patterns:

Move through a list left-to-right, computing a new store:

``````a = 0
for x in [12,17,1,42]:
a = a+x
b = False
for x in [True,True,False]:
b = b or x``````
``````fold (+) 0 [ 12 ; 17 ; 1 ; 42 ]

fold (||) false [ true ; true ; false ]
``````

Compute a recursive result on the tail and then process the current element:

``````reduce (^) [ "a" ; "string" ; "list" ] ""
reduce (fun c l -> (if c = '!' then ['!';'!';'1';'1'] else [c]) @ l)
(explode "I can haz happy!") []``````

# `fold`

`fold` “folds” the members of a list left-to-right using its first argument, given an initial value, so

``fold (+) 0 [1; 3; 2; 6] ≡ (((0 + 1) + 3) + 2) + 6``

and

``fold (||) false [true; false; false] ≡ ((false || true) || false) || false``

what about `fold (fun t h -> h::t) [] [1; 2; 3]`?

In Ocaml this is also called “fold left”, or `List.fold_left`

What is the type of `fold(_left)`?

``fold : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a``

How is it implemented in Ocaml?

``````let rec fold f acc l = match l with
| [] -> acc
| h::t -> fold f (f acc h) t``````

Example: implement `length` via `fold`:

``let length l = fold (fun acc _ -> acc+1) 0 l``

# `reduce`

`reduce` processes the members of a list by reducing the tail, combining with its first argument so:

``reduce (+) [1; 3; 2; 6] 0 ≡ 1 + (3 + (2 + (6 + 0)))``

and

``reduce (||) [true; false; false] false ≡ true || (false || (false || false))``

What about `reduce (fun h t -> h::t) [1; 2; 3] []`?

In Ocaml this is also called “fold right”, or `List.fold_right`

What is the type of `reduce`?

``reduce: ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b``

How is it implemented in Ocaml?

``````let rec reduce f l init = match l with
| [] -> init
| h::t -> f h (reduce f t init)``````

Example: implement `flatten : 'a list list -> 'a list` via reduce:

`` let flatten l = reduce (@) l []``

More examples:

`distinct: 'a list -> 'a list`

`listmax: 'a list -> 'a option`

`implode: char list -> string`

(note: String.make 1 c turns c into a string)

Which are better with `fold`? With `reduce`?

# `cs2041.org`

// reveal.js plugins