I have two lists :
let a = ["a";"b"];
let b = ["c";"d"];
I want an output list c such as :
c = ["a";"c";"a";"d";"b";"c";"b";"d"];
How to do it in ocaml as lists are immutable? I am new to it.
I have two lists :
let a = ["a";"b"];
let b = ["c";"d"];
I want an output list c such as :
c = ["a";"c";"a";"d";"b";"c";"b";"d"];
How to do it in ocaml as lists are immutable? I am new to it.
You would return a new list. If you really are interested in the cartesian product of the lists, then this should be enough:
let cartesian l l' =
List.concat (List.map (fun e -> List.map (fun e' -> (e,e')) l') l)
# cartesian ["a";"b"] ["c";"d"];;
- : (string * string) list = [("a", "c"); ("a", "d"); ("b", "c"); ("b", "d")]
If you need that strange flat structure instead, you can use an additional list concatenation.
let flat_cartesian l l' =
List.concat (List.concat (
List.map (fun e -> List.map (fun e' -> [e;e']) l') l))
If you do not want to use concatenation, because this is not a tail recursive operation, you can use the following (which should be more efficient):
let product l1 l2 =
List.rev (
List.fold_left
(fun x a ->
List.fold_left
(fun y b ->
b::a::y
)
x
l2
)
[]
l1
)
;;
For the cartesian product, just change
b::a::y
into
(a,b)::y
I would break the problem into two sub problems:
Firstly consider a function appendeach with takes a value and a list and returns the result of adding that value infront of each item in the list
let rec appendeach x lst = match lst with [] -> []
| hd::tl -> x::hd::(appendeach x tl);;
Then consider a function product with takes two lists and calls appendeach for each item in the first list and the whole second list
let rec product lst1 lst2 = match lst1 with [] -> [] |
hd::tl -> (appendeach hd lst2)@(product tl lst2);;