Home > Net >  How to convert list of lists into tuples in Haskell, adding some specifications
How to convert list of lists into tuples in Haskell, adding some specifications

Time:06-04

I have a list of lists : [[43525,3,2],[43615,2,2],[41111,1,2],[74855,5,3]]
I want to convert this list into a list of tuples, taking only the second and the last elements of every list. And adding 15*i every time I map on the list (i is the index).

taking the first example: [[43525,3,2],[43615,2,2],[41111,1,2],[74855,5,3]]
I want somthing like : [(3,2) , (17, 2), (31, 2), (50, 3)]

17 = 3 (15*1)
31 = 1 (15*2)
50 = 5 (15*3)

I already create a function that take a list of lists and convert it to a list of tuples: 
From this [[43525,3,2],[43615,2,2],[41111,1,2],[74855,5,3]]
to this [(3,2),(2,2),(1,2),(5,3)]

    tupleInfo [[]] = []
    tupleInfo [[_,x,y]] = [(x,y)]
    tupleInfo list = map (\[_,x,y] -> (x,y)) list 

CodePudding user response:

You are trying to do two different things: first you want to turn the list of lists in a list of tuples, second you want to add 15*i to the second element of each tuple. Let's try to write two different functions and then compose them together:

convertToTuples :: [[Int]] -> [(Int, Int)]
convertToTuples [[]] = []
convertToTuples xs = map (\[_, x, y] -> (x, y)) xs

If you take a closer look it is exactly as the fist version of tupleInfo you wrote except it removes the second case which is redundant: map already correctly handles that.

add15 :: [(Int, Int)] -> [(Int, Int)]
add15 xs = zipWith (\idx (x, y) -> (x 15*idx, y)) [0..] xs

As you suggested it is pretty straightforward using the zipWith function. Now you can obtain the solution by composing the two functions together:

solution :: [[Int]] -> [(Int, Int)]
solution xs = add15 (convertToTuples xs)
-- in a more Haskell-y way you could write:
-- solution = add15 . convertToTuples

I always prefer to decompose the domain logic in small self-contained functions that can then be composed, this way it is easier to reason about each step.

CodePudding user response:

The answer was simple. I used the Zipwith function.

    tupleInfo [[]] = []
    tupleInfo [[_,x,y]] = [(x,y)]
    tupleInfo list =  zipWith (\[_,x,y] i -> (x 15*i,y)) list [0..]
  • Related