CSCI 2041

ADVANCED PROGRAMMING PRINCIPLES

List Functions:

fold and reduce

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] 01 + (3 + (2 + (6 + 0)))

and

reduce (||) [true; false; false] falsetrue || (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