Haskell-чередующиеся элементы из двух списков

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

у меня есть функция:

blend xs ys

пример:

blend [1,2,3] [4,5,6]

должен возвратить

[1,4,2,5,3,6]

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

Он удаляет их из их кортежи, которые я не могу понять, как реализовать.

4 ответов


Как насчет обмена аргументами во время рекурсии-descend?

blend (x:xs) ys = x:(blend ys xs)
blend _ _ = []

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

blend _ ys = ys

Я предполагаю, что это домашнее задание. При условии, что вы можете создать следующий список (как вы сказали):

[(1,4),(2,5),(3,6)]

... вы можете решить его с помощью 2 функций:

  1. вам нужно преобразовать кортеж (a, b) в список [a, b]. Попробуйте использовать сопоставление шаблонов! Эта функция должна быть применена (aka. сопоставляется) по всем элементам списка.
  2. у вас будет список списков, как [[1,4],[2,5],[3,6]], поэтому вам нужна функция для конкатенации подсписков в один большой список.

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


Если вы хотите 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]]

решение без использования concat или явной рекурсии:

blend l = foldr($)[] . zipWith(.) (map(:)l) . map(:)

мы можем сделать также сделать этот пункт-бесплатно

blend' = (foldr($)[].) . (.map(:)) . zipWith(.) . map(:)


Как это работает: сначала украсьте оба списка операторами минусов
\[1,2,3] [4,5,6] -> [1:, 2:, 3:] [4:, 5:, 6:]

затем мы zip это вместе с функцией composition

-> [(1:).(4:), (2:).(5:), (3:).(6:)]

и, наконец, сложите приложение всех этих композиций справа от пустого списка

-> (1:).(4:) $ (2:).(5:) $ (3:).(6:) $ [] = 1:4:2:5:3:6:[] = [1,4,2,5,3,6]