2013-10-18 9 views
5

Sto provando a scrivere una funzione simile a zip ma che non scarterà elementi extra. Mi sento come se avessi fatto un errore davvero stupido da qualche parte.Cosa c'è di sbagliato nella mia versione modificata di zip?

ingresso Esempio:

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

uscita desiderata:

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

Ciò però non verrà compilato.

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

si sta chiamando 'zip' invece di chiamare il tuo modo ricorsivo' zipMaybe'. – Tarmil

+4

Potrebbe piacerti ['align'] (http://hackage.haskell.org/package/these-0.3/docs/Data-Align.html). –

+0

@DanielWagner ringrazia, 'padAlign' fa esattamente quello che sto cercando. – mcjohnalds45

risposta

9

Si dovrebbe chiamare zipMaybe in modo ricorsivo, invece di arretrare di vaniglia zip, che ha il tipo sbagliato. .

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

Btw, c'è una definizione più breve di questa funzione:

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

Che ne dici di 'map (\ x -> (Just x, Nothing)) xs' invece di' map', 'zip' e' repeat'? –

+0

@DanielWagner: quindi preferirei una comprensione. Vedi risposta aggiornata. –

+0

'map' probabilmente sembra più chiaro di una comprensione qui – alternative

Problemi correlati