在 Haskell 中掩码合并两个字符串的优雅方法

Evg*_*Evg 1 merge haskell list

例如,如果我们有两个字符串"abc"并且"1234"我想要结果"abc4"(第一个字符串掩码第二个)。(如果我们将它们垂直绘制,就像波浪从左侧传来并拉动字符)

             "a"  "1"            "a"
 wave ->     "b"  "2"   result   "b" 
             "c"  "3"            "c"
                  "4"            "4"  
Run Code Online (Sandbox Code Playgroud)

我从 Haskell 的解决方案开始

slice from to xs = take (to - from + 1) (drop from xs)
merge l1 l2 = if length l2 > length l1 
                then l1 ++ slice (length l1) (length l2) l2 
                else l1
Run Code Online (Sandbox Code Playgroud)

您能提供一些更优雅\紧凑的解决方案吗?

kar*_*kfa 7

你只需要一个特殊的合并功能

> let merge [] ys = ys
|     merge xs [] = xs
|     merge (x:xs) (y:ys) = x : merge xs ys
Run Code Online (Sandbox Code Playgroud)

或使用drop

> let merge2 x y = x ++ drop (length x) y
Run Code Online (Sandbox Code Playgroud)


Wil*_*ess 5

你想要一个“ zipLongest”,transpose就像这样:

maskMerge1 :: [b] -> [b] -> [b]
maskMerge1 as bs  =  map head $ transpose [as,bs]
              -- or:
              --        head <$> transpose [as,bs]
Run Code Online (Sandbox Code Playgroud)

这是相当紧凑和优雅的(非常感谢@leftaroundabout的评论!)。

从上面看,

    [ "abc" ,        [ ['a' ,'b' ,'c'     ] ,
      "1234" ]         ['1' ,'2' ,'3' ,'4'] ]
    ----------      --------------------------
                     [  "a1","b2","c3","4"  ]   -- transpose
    ----------      --------------------------
      "abc4"         [  'a' ,'b' ,'c' ,'4'  ]   -- map head
Run Code Online (Sandbox Code Playgroud)

另一个答案中的代码length也可以工作,甚至对于无限x,尽管调用了 dreaded ,但由于调用了 ,length它将在内存中保留整个。xlength