Если ваш список результатов должен содержать элементы, состоящие из элементов обоих подсписков, то вам, очевидно, придется деструктурировать каждый подсписок на каждой итерации.
Если гарантируется, что списки имеют одинаковую длину, решение может быть простым:
let rec zip paired_lists =
match paired_lists with
| [], [] -> []
| h1::t1, h2::t2 -> (h1, h2)::(zip (t1, t2))
| _, _ -> failwith "oops, the lists seems to have different lengths"
;;
zip ([1;2;3], [4;5;6]);;
- : (int * int) list = [(1, 4); (2, 5); (3, 6)]
Но этот не является хвост-рекурсивным, что, очевидно, не хорошо. Вторая неоптимальная вещь - это реконструкция набора списков на каждой итерации (я новичок ie в OCaml, так что скорее всего компилятор достаточно умен, чтобы избежать ненужных распределений, но все же ...). Исправление обоих fl aws тоже тривиально:
let zip_tr paired_lists =
let list1, list2 = paired_lists in
let rec aux l1 l2 acc =
match l1, l2 with
| [], [] -> List.rev acc
| h1::t1, h2::t2 -> aux t1 t2 (h1, h2)::acc
| _, _ -> failwith "oops, the lists seems to have different lengths"
in aux list1 list2 []
;;
zip_tr ([1;2;3], [4;5;6]);;
- : (int * int) list = [(1, 4); (2, 5); (3, 6)]