Converting tuples

Asked by At

I want to write a functions which takes the input parameter xs, which represents a list of tuples of the form (a,b,cs) and convert it to a list of tuples (a*b,b+c), for a and b representing whole numbers and all elements c in cs with cs representing a list of numbers.

The result should only include tuples in which the first element of the tuple is bigger but not even than its second element.

Example:

  [(13,25,[1,12,101]), (5,6,[7,17,27])]

  -- should be converted to 

  [(325,26),(325,37),(325,126),(30,13)]

Update: After a lot of testing i found this solution but I am not quite sure how to remove the tuples which do not match the requirements from the resulting list:

  convert :: [(Int, Int, [Int])] -> [(Int, Int)]
  convert xs = [(a*b,b+c) | (a,b,cs) <- xs, c <- cs]

1 Answers

3
Willem Van Onsem On Best Solutions

You simply need to iterate further on the third element. We furthermore should add a filter a boolean expression in the "body" of the list-comprehension that is checked such that only items satisfying this condition are added:

convert xs :: (Num a, Ord a) => [(a, a, a)] -> [(a, a, a)]
convert xs = [ (a*b,b+c) | (a, b, cs) <- xs, c <- cs, a*b > b+c ]

we thus unpack the tuples in the original list xs, and then use cs (the third item of the tuple) as the source of the second generator.

For example:

Prelude> convert [(13,25,[1,12,101]), (5,6,[7,17,27])]
[(325,26),(325,37),(325,126),(30,13),(30,23)]

Or we can use filter :: (a -> Bool) -> [a] -> [a] instead:

convert xs :: (Num a, Ord a) => [(a, a, a)] -> [(a, a, a)]
convert xs = filter (uncurry (>)) [ (a*b,b+c) | (a, b, cs) <- xs, c <- cs ]