Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List of tuples to just list using map haskell

Tags:

haskell

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?

like image 300
overwriter Avatar asked Mar 20 '12 12:03

overwriter


2 Answers

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
like image 191
ehird Avatar answered Oct 19 '22 06:10

ehird


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]
like image 45
Darren Avatar answered Oct 19 '22 07:10

Darren