Hi, I hope you have nice vacations !
I wanted to write a "lists_product" function that could apply a
function f on each generated term, from a list of lists. Not
interested in mixing types of lists ( that would raise other problems
). All can be simply int lists.
This works for 3 lists (could be of any kind here). *)
let _3lists_product f l1 l2 l3 =
List.iter
(fun e1 ->
List.iter
(fun e2 ->
List.iter
(f e1 e2)
l3)
l2)
l1
let _ = _3lists_product
(fun x y z -> Printf.printf "(%i, %i, %i) " x y z)
[1; 3; 5] [2; 4] [10; 100]
(* ->
(1, 2, 10) (1, 2, 100) (1, 4, 10) (1, 4, 100)
(3, 2, 10) (3, 2, 100) (3, 4, 10) (3, 4, 100)
(5, 2, 10) (5, 2, 100) (5, 4, 10) (5, 4, 100)
or, partially applying f by nesting step :
*)
let _3lists_product2 f l1 l2 l3 =
List.iter
(fun e ->
let f = f e in
List.iter
(fun e ->
let f = f e in
List.iter
(fun e ->
let f = f e in
f)
l3)
l2)
l1
(* But how to cleanly write this, with a true list of lists ?
How to avoid repeated code ?
This compiles :
*)
let lists_product4 f =
function
[] ->
f
| _ ->
assert false
let lists_product3 f =
function
[] ->
assert false
| h::t ->
List.iter
(fun e -> lists_product4 (f e) t)
let lists_product2 f =
function
[] ->
assert false
| h::t ->
List.iter
(fun e -> lists_product3 (f e) t)
h
let lists_product f =
function
[] ->
assert false
| h::t ->
List.iter
(fun e -> lists_product2 (f e) t)
h
let _ = lists_product
(fun x y z -> Printf.printf "(%i, %i, %i) " x y z)
[[1; 3; 5]; [2; 4]; [10; 100]]
(* All right above.
But when I try to unify/compact all these repeated things below,
there is a compile error : *)
let rec lists_product f =
function
[] ->
f
| h::t ->
List.iter
(fun e -> lists_product (f e) t)
(* ^^^^^
This expression has type 'a but is here used with type 'b -> 'a *)
h
let _ = lists_product
(fun x y z -> Printf.printf "(%i, %i, %i) " x y z)
[[1; 3; 5]; [2; 4]; [10; 100]]
(* Moreover, I suspect to get problems with a fixed number of
parameters function f that should match the length of the list of lists...
Please do you have advices to properly write this "lists_product" ?
Thanks
Fabrice