Probably of interest to no one as I’m just dabbling but thought I’d share some code I’d written to try and compare to lists and return the items at the point they differ. First the embarrassing “why wont this language to what I want it to?” version:

```
module ListEx : sig
val mismatch : 'a list -> 'a list -> 'a option * 'a option
end = struct
let mismatch a b =
(* must: a_len <> b_len *)
let find_missing a b =
(* where list a is longer than b *)
let find_missing_left a b =
let len = List.length b in
match List.findi ~f:(fun i _ -> i = len) a with
| None -> assert false (* shouldn't happen as expected must be longer than found *)
| Some (_, x) -> Some x, None (* the first expected item that has no match in found *)
in
(* where list b is longer than a *)
let find_missing_right a b =
match find_missing_left b a with
| b, a -> a, b
in
if List.length a > List.length b then
find_missing_left a b
else
find_missing_right a b
in
(* find the mismatching pair *)
let mismatch' ab =
(* true when a pair are unmatched *)
let unmatched = function
| a, b when a <> b -> true
| _ -> false
in
match List.find ~f:unmatched ab with
| None -> None, None (* OK all match *)
| Some (a, b) -> Some a, Some b (* Some mismatch found *)
in
match List.zip a b with
| None -> find_missing a b (* lists of different lengths *)
| Some ab -> mismatch' ab (* list of same length *)
end
```

Then the slightly less embarrassing version:

```
module ListEx : sig
val mismatch : 'a list -> 'a list -> 'a option * 'a option
end = struct
let rec mismatch a b =
match (List.hd a), (List.hd b) with
| Some a', Some b' when a' = b' -> mismatch (List.tl_exn a) (List.tl_exn b)
| x, y -> x, y
end
```

That’s quite some line count difference. Unfortunately I’m finding I’m mainly writing code like the former at the moment.