Если вы хотите повторно использовать btwn
, вы в основном хотите реализовать это: *
fun a b ->
let la = btwn 0 a
and lb = btwn 0 b
in cartesian_product la lb;;
Теперь вам нужно только реализовать cartesian_product
, который в основном состоит из двух вложенных циклов: внешний цикл повторяет элементы a
из la
, и для каждого a
вы повторяете все элементы b
из lb
для построения списка [(ai,b0)
, ..., (ai,bj)]
. Затем вам нужно объединить все списки (один для a0
, затем a1
и т. Д.).
В псевдокоде это будет:
R = []
loop for a in la:
R := append(R, [(a,b) for b in lb])
Но вместо объединения вы можете связать результирующий список с параметрами и промежуточными возвращаемыми значениями, чтобы всегда добавлять только элементы впереди, что занимает постоянное время:
let cross_product la lb =
let rec outer sofar la =
match la with
| [] -> sofar
| a::la ->
let rec inner sofar lb =
match lb with
| [] -> sofar
| b::lb -> (inner ((a,b)::sofar) lb)
in outer (inner sofar lb) la
in outer [] la;;
Если вы не возражаете против наличия локального изменяемого состояния, несколько более простой подход будет выглядеть так:
open List;;
let cross_product la lb =
let stack = ref []
in iter (fun a -> iter (fun b -> stack := (a,b)::!stack) lb) la;
!stack;;