Useful generic functions are usually the result of composing useful generic functions; the fact that these are easy to write is, however, not an excuse for not having them in a rich prelude. Given a total function for splitting a list at a given point:

let rec split_at n = function | [] -> [], [] | l when n == 0 -> [], l | x :: xs -> let l, r = split_at (pred n) xs in x :: l, r

and the anamorphism on lists, the basic functional iteration scheme giving the list of results:

let rec unfold f e = match f e with | None -> [] | Some (x, e') -> x :: unfold f e'

then splitting a list into chunks just requires some assembly:

let chunks n = unfold (fun l -> match split_at n l with [], [] -> None | p -> Some p)

As another example, suppose we need a Procrustean function `fit`

that truncates a list or pads it with a value to a given length. Given an way to build an infinite list:

let all x = let rec l = x :: l in l

the desired function is just:

let fit n e l = fst (split_at n (l @ all e))

The only good thing about the paucity of `Pervasives`

is that it forces one to practice often this kind of finger exercises. At least they are pretty.

## 1 comment:

Of course,

take == fst % split_at, and similarly fordrop == snd % split_at.Post a Comment