我的改版拉链有什么问题?

mcj*_*s45 5 haskell compiler-errors

我正在尝试编写一个类似于zip但不会丢弃额外元素的函数.我觉得我在某个地方犯了一个非常愚蠢的错误.

输入示例:

zipMaybe [1,2,3] [1,2]
Run Code Online (Sandbox Code Playgroud)

期望的输出:

[(Just 1, Just 1), (Just 2, Just 2), (Just 3, Nothing)]
Run Code Online (Sandbox Code Playgroud)
zipMaybe :: [a] -> [b] -> [(Maybe a, Maybe b)]
zipMaybe (a:as) (b:bs) = (Just a, Just b) : zip as bs -- line with error
zipMaybe (a:as) [] = (Just a, Nothing) : zip as []
zipMaybe [] (b:bs) = (Nothing, Just b) : zip [] bs
zipMaybe _ _ = []
Run Code Online (Sandbox Code Playgroud)

但是,这不会编译.

Test.hs:2:49:
    Couldn't match type `a' with `Maybe a'
      `a' is a rigid type variable bound by
          the type signature for
            zipMaybe :: [a] -> [b] -> [(Maybe a, Maybe b)]
          at Test.hs:1:13
    Expected type: [Maybe a]
      Actual type: [a]
    In the first argument of `zip', namely `as'
    In the second argument of `(:)', namely `zip as bs'
    In the expression: (Just a, Just b) : zip as bs
Run Code Online (Sandbox Code Playgroud)

Fre*_*Foo 9

你应该zipMaybe递归调用而不是退回到zip类型错误的vanilla .

zipMaybe :: [a] -> [b] -> [(Maybe a, Maybe b)]
zipMaybe (a:as) (b:bs) = (Just a, Just b) : zipMaybe as bs
zipMaybe (a:as) [] = (Just a, Nothing) : zipMaybe as []
zipMaybe [] (b:bs) = (Nothing, Just b) : zipMaybe [] bs
zipMaybe _ _ = []
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这个函数的定义较短:

zipMaybe (x:xs) (y:ys)  =  (Just x, Just y) : zipMaybe xs ys
zipMaybe xs     []      =  [(Just x, Nothing) | x <- xs]
zipMaybe []     ys      =  [(Nothing, Just y) | y <- ys]
Run Code Online (Sandbox Code Playgroud)

  • 怎么样`map(\ x - >(Just x,Nothing))xs`而不是`map`,`zip`和`repeat`? (2认同)