Не могу понять, как объединить два списка следующим образом в Haskell:
INPUT: [1,2,3,4,5] [11,12,13,14] OUTPUT: [1,11,2,12,3,13,4,14,5]
Я хочу предложить более ленивую версию слияния:
merge [] ys = ys merge (x:xs) ys = x:merge ys xs
В одном примере использования вы можете проверить недавний вопрос SO о отложенное создание комбинаций . Версия в принятом ответе неоправданно строга во втором аргументе, и вот что здесь улучшено.
merge :: [a] -> [a] -> [a] merge xs [] = xs merge [] ys = ys merge (x:xs) (y:ys) = x : y : merge xs ys
Так почему же вы думаете, что простой (concat. Transpose) "недостаточно хорош"?Я предполагаю, что вы пробовали что-то вроде:
merge :: [[a]] -> [a] merge = concat . transpose merge2 :: [a] -> [a] -> [a] merge2 l r = merge [l,r]
Таким образом, вы можете избежать явной рекурсии (против первого ответа), и все же это проще, чем второй ответ.Так в чем же недостатки?
РЕДАКТИРОВАТЬ: Посмотрите на ответ и комментарии Ed'ka!
Другая возможность:
merge xs ys = concatMap (\(x,y) -> [x,y]) (zip xs ys)
Или, если вам нравится Applicative:
merge xs ys = concat $ getZipList $ (\x y -> [x,y]) <$> ZipList xs <*> ZipList ys
Конечно, дело за развертывание:
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))
-- ++ pp [] [] = [] pp [] (h:t) = h:pp [] t pp (h:t) [] = h:pp t [] pp (h:t) (a:b) = h : pp t (a:b)