Let lst
be a List with tuples which I want to reverse each (The order of the tuples needs to be the same). For example:
[(a,b);(c,d)] -> [(b,a);(d,c)]
I know that it can be done with map:
List.map (fun (a,b) -> (b,a)) [(1,2);(3,4)];;
- : (int * int) list = [(2, 1); (4, 3)]
But I´m looking for a way to achieve it with List.fold_left
. My approach is to match the list with []
as a accumulator to concatenate every reversed tuple together, but I keep getting type-Errors:
List.fold_left (fun (a,b) -> (b,a)) [] lst;;
CodePudding user response:
List.fold_left
takes three arguments:
- A function of type
'a -> 'b -> 'a
- An accumulator of type
'a
- A list of type
'b list
Your function (fun (a,b) -> (b,a))
is missing an argument, the accumulator, on which you want to concatenate the reversed pairs
(fun acc (a,b) -> (b,a) :: acc)
CodePudding user response:
Both the answer by @Lhooq and @rithvik are mostly spot-on, but will reverse the order of the tuples in the resulting list.
We either need to feed the result to List.rev
or use List.fold_right
.
utop # List.fold_left (fun acc (a, b) -> (b, a) :: acc) [] [(1, 2); (3, 4)] |> List.rev;;
- : (int * int) list = [(2, 1); (4, 3)]
utop # List.fold_right (fun (a, b) acc -> (b, a) :: acc) [(1, 2); (3, 4)] [];;
- : (int * int) list = [(2, 1); (4, 3)]
CodePudding user response:
Using List.map
seems like a natural option here, because you could do something like:
List.map (fun (a, b) -> (b, a)) lst
But if you wanted to use List.fold_left
then you need to reverse each pair and then cons it to the accumulator list:
List.fold_left (fun acc (a, b) -> (b, a)::acc) [] lst
Since fold_left takes the following function signature: ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
, you need to make sure that your first argument is a function that takes in an accumulator list and an individual list element (in this case a tuple), and then returns a list.
EDIT: @Chris rightly pointed out that with this solution the order of the tuples themselves would also flip. You can fix this by wrapping the function with List.rev
, or instead of cons-ing you can append the tuple to the end of the list:
List.fold_left (fun acc (a, b) -> acc@[(b, a)]) [] lst