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]