28

无法弄清楚如何在 Haskell中以下列方式合并两个列表:

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

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

6 回答 6

65

我想提出一个更懒惰的合并版本:

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

对于一个示例用例,您可以查看最近关于延迟生成组合的 SO 问题。
接受的答案中的版本在第二个参数中是不必要的严格,这就是这里改进的地方。

于 2010-10-21T12:01:41.327 回答
51
merge :: [a] -> [a] -> [a]
merge xs     []     = xs
merge []     ys     = ys
merge (x:xs) (y:ys) = x : y : merge xs ys
于 2010-10-14T23:50:47.720 回答
25

那么为什么你认为简单的(concat . transpose)“不够漂亮”?我假设你已经尝试过类似的东西:

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

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

因此,您可以避免显式递归(与第一个答案相比),它仍然比第二个答案更简单。那么有什么缺点呢?

于 2010-10-15T12:08:05.960 回答
6

编辑:看看 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
于 2010-10-15T11:08:00.930 回答
4

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))
于 2013-08-27T08:41:16.227 回答
-1
-- ++
pp [] [] = []
pp [] (h:t) = h:pp [] t
pp (h:t) [] = h:pp t []
pp (h:t) (a:b) = h : pp t (a:b)
于 2012-05-07T09:03:27.273 回答