Haskell中的zip函数

Glo*_*ove 6 recursion implementation haskell

zip函数的实现,它将两个列表作为参数并返回一对新的对列表.到目前为止我得到了这个

myZip [] [] = []
myZip (x:xs) (y:ys) = [(x,y)] ++ myZip xs ys
Run Code Online (Sandbox Code Playgroud)

任何帮助?

Don*_*art 7

实际上只有一种方法可以为列表编写它,即使是作业:

zip :: [a] -> [b] -> [(a,b)]
zip (a:as) (b:bs) = (a,b) : zip as bs
zip _      _      = []
Run Code Online (Sandbox Code Playgroud)

或者,更一般地说,

zipWith :: (a -> b -> c) -> [a]->[b]->[c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _      _      = []
Run Code Online (Sandbox Code Playgroud)

如果你想变得古怪,并使用流融合,流融合纸的版本,自动机风格,

zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
zipWith f (Stream next0 sa0) (Stream next1 sb0) = Stream next (sa0, sb0, Nothing)
  where
    next (sa, sb, Nothing) = case next0 sa of
        Done        -> Done
        Skip    sa' -> Skip (sa', sb, Nothing)
        Yield a sa' -> Skip (sa', sb, Just a)

    next (sa', sb, Just a) = case next1 sb of
        Done        -> Done
        Skip    sb' -> Skip          (sa', sb', Just a)
        Yield b sb' -> Yield (f a b) (sa', sb', Nothing)
Run Code Online (Sandbox Code Playgroud)

  • 但是,在这种情况下,使用`(a,b):...`和`[(a,b)] ++ ...`之间应该没有区别.前者更简单,也更惯用,但语义和性能应该相同(编译器只会将后者展现给前者) (3认同)
  • 这个答案实现了zip,但没有批评提问者的版本或解释为什么它以它的方式实现.有待改善. (3认同)