I want to convert list of tuples: [(2,2,2), (3,3,3), (4,4,4), (5,5,5)] to just list: [2,2,2,3,3,3,4,4,4,5,5,5]
I try this
map (\(a,b,c,d)->a:b:c:d) listOfTuples
but get an error.
Prelude> map (\(a,b,c)->a:b:c) [(1,2,3), (5,6,7)]
<interactive>:1:37:
No instance for (Num [t])
arising from the literal `7' at <interactive>:1:37
Possible fix: add an instance declaration for (Num [t])
In the expression: 7
In the expression: (5, 6, 7)
In the second argument of `map', namely `[(1, 2, 3), (5, 6, 7)]'
Prelude>
How can I do it with lambda? And why my stuff does not work?
a:b:c:d
is invalid because it's a : (b : (c : d))
. (:)
takes a list on the right-hand side and an element to prepend to it on the left-hand side, but d
is another element, not (necessarily) a list. You probably mean a:b:c:d:[]
, which is the same as [a,b,c,d]
.
If you make that change, the code will run, and produce [[2,2,2], [3,3,3], [4,4,4], [5,5,5]]
, since map
applies the function to each element of the list, and uses its result as the new element; that is, cannot change the structure of the list, only each element independently. If you want it flattened, you'll need to use concat
(which has the type [[a]] -> [a]
, and flattens a list of lists):
concat (map (\(a,b,c,d) -> [a,b,c,d]) listOfTuples)
However, there is a ready-made composition of concat
and map
, which is more idiomatic to use:
concatMap (\(a,b,c,d) -> [a,b,c,d]) listOfTuples
This can also be done more succinctly with a list comprehension.
Assuming:
let listOfTuples = [(2,2,2), (3,3,3), (4,4,4), (5,5,5)]
then this list comprehension:
concat [[a,b,c] | (a, b, c) <- listOfTuples]
produces:
[2,2,2,3,3,3,4,4,4,5,5,5]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With