← Back to the lab

Problem 3: Array.for_all

For is_win.

Checking a condition against every element

Array.for_all p a returns true exactly when p returns true for every element of a. An empty array vacuously satisfies any p.

let all_even = Array.for_all (fun n -> n mod 2 = 0)
let _ = all_even [| 2; 4; 6 |]   (* = true *)
let _ = all_even [| 2; 3; 6 |]   (* = false *)

This reads almost like English: "for all elements, p holds." A scored guess wins exactly when every one of its five entries is Correct -- there's no need to count anything or write a recursive helper, Array.for_all already is that check.

The list equivalent

The same idea exists for lists as List.for_all, with the identical signature shape (('a -> bool) -> 'a list -> bool instead of ('a -> bool) -> 'a array -> bool). Reach for whichever matches the data structure you already have.

let _ = List.for_all (fun n -> n > 0) [1; 2; 3]   (* = true *)

It's not magic

Like List.mem, Array.for_all is just an ordinary loop under a name:

let for_all_manual p a =
  let ok = ref true in
  Array.iter (fun x -> if not (p x) then ok := false) a;
  !ok

Once one condition fails, ok never becomes true again. Reaching for Array.for_all instead of writing this out every time is the whole point of a standard library: the loop shape is common enough that it has its own name.