Haskell превращает список кортежей в список списков

#haskell #functional-programming #lazy-evaluation

#haskell #функциональное программирование #ленивая оценка

Вопрос:

Я пытаюсь превратить список кортежей в список списков. Например, если у меня есть список [(9,1), (6,3), (4,1)] , то это превратится в [[9, 6, 4],[6],[6]] . Происходит то, что в списке кортежей [(a,b)] , a представляет собой число от 0 до 9 и b представляет вхождение этого числа, a всегда будет уникальным.

Что я пытаюсь сделать, так это пройтись по списку n раз, где n = maximum b in the list of tuples. каждый раз, когда я просматриваю список, я беру a и помещаю его в список, затем уменьшаю b на 1. Если b == 0 тогда я просто пропускаю это.

Итак, из моего примера я беру [9,6,4] и добавляю их в список, затем уменьшаю b значение каждого из них, так что теперь список будет выглядеть так [(9,0),(6,2),(4,0)] . Затем, повторяя, я беру [6] , список кортежей теперь выглядит так [(9,0), (6,1), (4,0)] . Наконец, сделайте [6] последний раз, и теперь когда-либо b в списке кортежей есть 0 , так что это сделано.

Я создал функцию, которая принимает 1-й элемент из списка кортежей, если b значение >= 1, но я не знаю, как я могу повторить это по обновленному списку со всеми `b — 1′ для каждого кортежа.

 turnIntList :: [(Integer, Integer)] -> [[Integer]]
turnIntList [] = []
turnIntList x = ([map ((a, b) -> case (a,b) of  _ | b >= 1 -> a | otherwise -> -1) x])
  

Я также попытался создать другую вспомогательную функцию, которая принимает список кортежей и преобразует их в список в зависимости от того, насколько велик b . Из основной функции я бы попытался отправить [(a, 1), (b, 1) …] для создания списка, а затем отслеживать уменьшение b здесь, пока это не будет сделано. Итак, для этой функции:

 pairingL :: [(Integer, Integer)] -> [Integer] -> [Integer]
pairingL ((a,b):xs) l -- = if b /= 0 then [a,b-1] else []
    | null xs = if b == 1 then [a]    l else if b > 1 then [a]    l    pairingL [(a,b-1)] l else l
    | otherwise = 
        if b /= 0 then [a]    l    pairingL ((a,b-1):xs) l else pairingL xs l


pairingL [(9,1), (7,2), (5,1)]
[9,7,7,5]

pairingL [(1,1), (2,1), (3,1)]
[1,2,3]

pairingL [(1,2), (2,2), (3,2)]
[1,1,2,2,3,3]
  

Я пытался разархивировать список и работать с ним, итерацией и повторением, но я не могу понять, как заставить функцию многократно просматривать список и обновлять список новыми b значениями, а затем снова запускать.

В заключение, то, что я пытаюсь сделать, это что-то вроде:

     turnIntList [(9,3),(5,1),(2,1)]
    [[9,5,2],[9],[9]]

    turnIntList [(1,1),(2,1),(3,1),(4,1)]
    [[1,2,3,4]]

    turnIntList [(1,2),(2,2),(3,2)]
    [[1,2,3],[1,2,3]]

    turnIntList [(4,2),(6,1)]
    [[4,6],[4]]
  

Процесс:
Я беру первый элемент из кортежей, добавляю их в список, затем вычитаю второй элемент на 1. После выполнения этого для каждого кортежа в списке я повторяю процесс до тех пор, пока все вторые элементы для каждого кортежа не будут равны 0

Важные примечания: опять же, в списке кортежей [(a,b)], a ВСЕГДА будет УНИКАЛЬНОЕ число от 0 до 9, и b >= 0

Комментарии:

1. У вас есть для нас другие примеры?

2. @Elmex80s Извините, я должен был привести более 1 примера. Я добавил еще несколько и более четко объяснил процесс

3. Спасибо. Ввода-вывода достаточно. Первый шаг в цикле может отвлекать

4. Для вашего развлечения, turnIntList = transpose . map (uncurry (flip replicate)) тоже работает, хотя технически с подписью, [(a, Int)] -> [[a]] используя Int вместо Integer .

5. Или даже короче, turnIntList = (>>= uncurry (flip replicate)) .

Ответ №1:

Это может

 turnIntList :: [(Integer, Integer)] -> [[Integer]]
turnIntList [] = [] -- if it doesn’t compile use [[]]
turnIntList ls = [i | (i, _) <- ls] : turnIntList [(i, n - 1) | (i, n) <- ls, n - 1 > 0]
  

Комментарии:

1. Я знал, что должно быть более простое решение с пониманием списка. Я довольно новичок в Haskell, и это одна из областей, в которых я все еще довольно слаб. Обязательно прочитаю об этом подробнее. Одна вещь, которую я не понимаю, я бы предположил, что это вызовет ошибку n не в области видимости, поскольку она нигде явно не объявлена, однако это работает отлично.

2. n связан соответствием шаблону понимания внутреннего списка @WilliamJones