Подтвердить что ты не робот

Объединение двух списков в Haskell

Невозможно определить, как слить два списка следующим образом в Haskell:

INPUT:  [1,2,3,4,5] [11,12,13,14]

OUTPUT: [1,11,2,12,3,13,4,14,5]
4b9b3361

Ответ 1

merge :: [a] -> [a] -> [a]
merge xs     []     = xs
merge []     ys     = ys
merge (x:xs) (y:ys) = x : y : merge xs ys

Ответ 2

Я хочу предложить более ленивую версию слияния:

merge [] ys = ys
merge (x:xs) ys = x:merge ys xs

В одном примере использования вы можете проверить недавний вопрос SO о ленивом поколении комбинаций.
Версия в принятом ответе излишне строго во втором аргументе и что здесь улучшено.

Ответ 3

Итак, почему вы думаете, что простой (concat. transpose) "недостаточно"? Я предполагаю, что вы пробовали что-то вроде:

merge :: [[a]] -> [a]
merge = concat . transpose

merge2 :: [a] -> [a] -> [a]
merge2 l r = merge [l,r]

Таким образом, вы можете избежать явной рекурсии (против первого ответа) и все же проще, чем второй ответ. Итак, каковы недостатки?

Ответ 4

РЕДАКТИРОВАТЬ: взгляните на ответ Эд'ка и комментарии!

Другая возможность:

merge xs ys = concatMap (\(x,y) -> [x,y]) (zip xs ys)

Или, если вам нравится Аппликация:

merge xs ys = concat $ getZipList $ (\x y -> [x,y]) <$> ZipList xs <*> ZipList ys

Ответ 5

Конечно, случай разворачивания:

interleave :: [a] -> [a] -> [a]
interleave = curry $ unfoldr g
  where
    g ([], [])   = Nothing
    g ([], (y:ys)) = Just (y, (ys, []))
    g (x:xs, ys) = Just (x, (ys, xs))

Ответ 6

-- ++
pp [] [] = []
pp [] (h:t) = h:pp [] t
pp (h:t) [] = h:pp t []
pp (h:t) (a:b) = h : pp t (a:b)