2013-10-18 1 views
5

私はzipに似ているが余分な要素を破棄しない関数を書こうとしています。私はどこかで本当に愚かな誤りを犯したような気がします。変更されたバージョンのzipで何が問題になっていますか?

例入力:

zipMaybe [1,2,3] [1,2] 

所望の出力:

[(Just 1, Just 1), (Just 2, Just 2), (Just 3, Nothing)] 

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 _ _ = [] 

これは、しかし、コンパイルされません。

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 
+2

あなたが代わりに再帰的にあなたの 'zipMaybe'を呼び出すzip''呼んでいる:

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 _ _ = [] 

はところで、この機能の短い定義があります。 – Tarmil

+4

['align'](http://hackage.haskell.org/package/these-0.3/docs/Data-Align.html)が好きかもしれません。 –

+0

@DanielWagnerさん、ありがとう、 'padAlign'は私が探しているものとまったく同じです。 – mcjohnalds45

答えて

9

代わりに間違った型を持っているバニラzipにバックオフの再帰的zipMaybeを呼び出す必要があります。 。

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] 
+2

'map'、' zip'、 'repeat'の代わりに' map(\ x - >(Just x、Nothing))xs'はどうですか? –

+0

@DanielWagner:私は理解したいです。更新された回答をご覧ください。 –

+0

'map'はおそらくここの理解よりもはっきりしています – alternative

関連する問題