I’ve been trying to add a list to a list of lists.
What I want :
l1 : [[]] / [] / Empty list
l2 : [1;2]
result : [[1;2]]
add [1;3] to result :
result : [[1; 2]; [1; 3]]
I’ve tried to play with the @ and the :: operator for quite a while now, still no results.
Here’s my problem :
type sign = Neg | Zero | Pos | Error
let all_pairs (l1: sign list) (l2 : sign list) : sign list list =
let rec aux acc list =
match list with
| [] -> acc
| hd :: tl ->
let rec m_aux m_acc m_list =
match m_list with
| [] -> aux (m_acc :: acc) tl
| m_hd :: m_tl -> m_aux (m_hd :: m_acc) m_tl
in m_aux [hd] l2
in aux [] l1
With a given L1, L2 which are sign list, return a sign list list with every combination of two signs x and y, x is in L1 and y is in L2
Example :
L1 : [Pos; Error]
L2 : [Neg; Zero]
all_pairs L1 L2 should return
[ [Pos; Neg]; [Pos; Zero]; [Error; Neg]; [Error; Zero] ]
In this exact order
>Solution :
I don’t understand your first line. But here’s a session showing how to build up the results you seem to be asking for:
# let l1 = [];;
val l1 : 'a list = []
# let l2 = [1;2];;
val l2 : int list = [1; 2]
# let result1 = l1 @ [l2];;
val result1 : int list list = [[1; 2]]
# let l3 = [1;3];;
val l3 : int list = [1; 3]
# let result2 = result1 @ [l3];;
val result2 : int list list = [[1; 2]; [1; 3]]
A problem is that you’re trying to extend your lists at the end. This isn’t natural (or efficient) in OCaml. If you think about a adding new value to the beginning of a list things are simpler.
# let result3 = l3 :: l1;;
val result3 : int list list = [[1; 3]]
# let result4 = l2 :: result3;;
val result4 : int list list = [[1; 2]; [1; 3]]
The :: operator adds a new value to the beginning of a list. There’s no single operator for adding to the end of a list (because it’s not natural or efficient).
Update
You can code your function like this:
let all_pairs l1 l2 =
List.concat
(List.map
(fun a -> List.map (fun b -> [a;b]) l2)
l1)
It works for me.