Преобразование кортежей - PullRequest
0 голосов
/ 12 мая 2019

Я хочу написать функцию, которая принимает входной параметр xs, который представляет список кортежей в форме (a, b, cs) и преобразует его в список кортежей (a * b, b + c), для a и b, представляющих целые числа, и все элементы c в cs с cs, представляющим список чисел.

Результат должен включать только кортежи, в которых первый элемент кортежа больше, но даже не его второй элемент.

Пример:

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

  -- should be converted to 

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

Обновление: после многих испытаний я нашел это решение, но я не совсем уверен, как удалить кортежи, которые не соответствуют требованиям, из полученного списка:

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

1 Ответ

3 голосов
/ 12 мая 2019

Вам просто нужно итерировать дальше по третьему элементу.Кроме того, мы должны добавить filter логическое выражение в "тело" списка-списка, которое проверяется таким образом, чтобы добавлялись только элементы, удовлетворяющие этому условию:

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

, таким образом, мы распаковываемкортежи в исходном списке xs, а затем используйте cs (третий элемент кортежа) в качестве источника второго генератора.

Например:

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

Или мы можем использовать filter :: (a -> Bool) -> [a] -> [a] вместо:

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