I need a function in OCaml that will take a type of
('a list * b' list) list
and make of it
'a list * b' list
. I have tried with the built in functions List.flatten and List.concat but they do not work, they require a type of 'c list list
. Can someone help me?

- 117
- 6
4 Answers
You have to use the functions List.split
and List.flatten
:
let my_function l =
let (fst_list, snd_list) = List.split l in
List.flatten fst_list, List.flatten snd_list ;;
First the split
function will generate and 'a list list
and a 'b list list
, then you just have to flatten
them.

- 2,537
- 16
- 21
You can do it using the function fold_left
like this :
You start with two empty lists working as accumulators. For every sub-lists in your the input list, you add the elements into the respective accumulator (elements of the first sub-list in the first accumulator and same thing for the second sub-list).
# let flatten l =
let (l1,l2) =
List.fold_left (fun (l1,l2) (x,y) ->
(x :: l1, y :: l2)) ([], []) l in
List.rev (List.flatten l1), List.rev (List.flatten l2);;
val flatten : ('a list * 'b list) list -> 'a list * 'b list = <fun>
#

- 2,899
- 1
- 17
- 33
-
This is ok, but I need something to do `('a list * 'b list) list -> 'a list * 'b list` and not `('a * 'b) list -> 'a list * 'b list` – measuretheory Jan 20 '16 at 22:55
-
But it is still not what I need :( The order is not so important, what is important is what the input in the function is. Your gives `('a * 'b) list -> 'a list * 'b list` and I need `('a list * 'b list) list -> 'a list * 'b list` – measuretheory Jan 20 '16 at 23:00
-
Look my answer please, the function have the excepted type. – alifirat Jan 20 '16 at 23:02
-
You seem to understand OCaml really good, this function I needed to finish another exercise that I posted up here, but even with this it does not work, if you have time it would be great if you could take a look at it http://stackoverflow.com/questions/34858154/ocaml-function-with-data-type-tree/34878701#34878701 I am working on it for days now and I still do not have an answer :/ – measuretheory Jan 20 '16 at 23:19
Unfortunately there is no map for tuples and you need to decompose - e.g. using using split and flatten:
let splcat x = match List.split x with | (a,b) -> (List.flatten a, List.flatten b) ;;
That's how it looks on the commandline:
utop # splcat [([1;2],["a"]); ([3],["uvw";"xyz"]) ] ;;
- : int list * bytes list = ([1; 2; 3], ["a"; "uvw"; "xyz"])

- 4,918
- 24
- 35
The following should work:
let split2 l = (List.map fst l, List.map snd l)
let flatten2' (l1, l2) = (List.flatten l1, List.flatten l2)
let flatten2 l = flatten2' (split2 l)
Here, split2
will turn a ('a list * 'b list) list
into a ('a list list * 'b list list)
(fst
and snd
return the first and second component of a pair, respectively) and flatten2'
will individually flatten the two components. And flatten2
will finally do what you require. You can also pack this into a single function, but I think this is easier to understand.
Note that neither List.map
nor List.flatten
is tail-recursive; if you need tail-recursive versions, there are other libraries that have them, or you can build them from the standard library using rev_xxx
functions or write them from scratch.

- 8,600
- 15
- 19