简体   繁体   English

在Haskell中合并两个列表

[英]Merging two lists in Haskell

Can't figure out how to merge two lists in the following way in Haskell: 无法弄清楚如何在Haskell 中以下列方式合并两个列表:

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

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

I want to propose a lazier version of merge: 我想提出一个更加懒惰的合并版本:

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

For one example use case you can check a recent SO question about lazy generation of combinations . 对于一个示例用例,您可以查看最近关于延迟生成组合的 SO问题。
The version in the accepted answer is unnecessarily strict in the second argument and that's what is improved here. 接受的答案中的版本在第二个参数中是不必要的严格,这是在这里改进的。

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

So why do you think that simple (concat . transpose) "is not pretty enough"? 那么为什么你认为那么简单(concat.transpose)“还不够”? I assume you've tried something like: 我假设你尝试过类似的东西:

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

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

Thus you can avoid explicit recursion (vs the first answer) and still it's simpler than the second answer. 因此,您可以避免显式递归(与第一个答案相比),但仍然比第二个答案更简单。 So what are the drawbacks? 那有什么缺点呢?

EDIT: Take a look at Ed'ka's answer and comments! 编辑:看看Ed'ka的回答和评论!

Another possibility: 另一种可能性

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

Or, if you like Applicative: 或者,如果你喜欢Applicative:

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

Surely a case for an unfold: 肯定是一个展开的案例:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM