Haskell - чередующиеся элементы из двух списков
Я пытаюсь написать функцию haskell, которая принимает два списка целых чисел и генерирует список с элементами, которые чередуются с двумя списками.
У меня есть функция:
blend xs ys
Пример:
blend [1,2,3] [4,5,6]
должен возвращать
[1,4,2,5,3,6]
Моя логика состоит в том, чтобы закрепить два списка вместе, создавая пары альтернативных элементов, а затем как-то удаляем их из своих кортежей.
Он удаляет их из своих кортежей, что я не могу понять, как их реализовать.
Ответы
Ответ 1
Как насчет обмена аргументами во время рекурсии-спуска?
blend (x:xs) ys = x:(blend ys xs)
blend _ _ = []
Вы даже можете обобщить этот подход для любого количества списков (я оставлю это вам) или взять остальные элементы списка, если другой пуст:
blend _ ys = ys
Ответ 2
Я буду считать, что это домашнее задание. При условии, что вы можете создать следующий список (как вы сказали):
[(1,4),(2,5),(3,6)]
... вы можете решить его с помощью двух функций:
- Вам нужно преобразовать кортеж
(a, b)
в список [a, b]
. Попробуйте использовать сопоставление шаблонов! Эта функция должна быть применена (ака. Сопоставлена) по всем элементам списка, который у вас есть.
- У вас будет список списков, например
[[1,4],[2,5],[3,6]]
, поэтому вам нужна функция для объединения подсписок в один большой список.
Есть, конечно, другие, возможно, более эффективные способы решения этой проблемы, но может быть хорошей идеей продолжить ваш оригинальный подход.
Ответ 3
Если вы хотите сделать zip, сгенерируйте списки вместо кортежей:
concat $ zipWith (\x y -> [x,y]) [1,2,3] [4,5,6]
Некоторая бессмысленная забава:
concat $ zipWith ((flip(:)).(:[])) [1,2,3] [4,5,6]
Вероятно, самый простой способ:
import Data.List
concat $ transpose [[1,2,3],[4,5,6]]
Ответ 4
Решение без использования concat
или явной рекурсии:
blend l = foldr($)[] . zipWith(.) (map(:)l) . map(:)
Мы можем сделать так, чтобы эта точка-свободная
blend' = (foldr($)[].) . (.map(:)) . zipWith(.) . map(:)
Как это работает: сначала украсить оба списка операторами cons
\[1,2,3] [4,5,6] -> [1:, 2:, 3:] [4:, 5:, 6:]
то мы запишем это вместе с композицией функций
-> [(1:).(4:), (2:).(5:), (3:).(6:)]
и, наконец, свернуть применение всех этих композиций справа на пустой список
-> (1:).(4:) $ (2:).(5:) $ (3:).(6:) $ [] = 1:4:2:5:3:6:[] = [1,4,2,5,3,6]