2011-01-23 10 views
10

Supponiamo di voler aggiungere due elenchi in Haskell. Qual è il modo più usuale per farlo?Qual è un modo idiomatico per aggiungere elenchi in Haskell?

Ecco quello che ho fatto:

addLists :: (Integral a) => [a] -> [a] -> [a] 
addLists xs ys = map add $ zip xs ys 
    where add (x, y) = x+y 
+3

BTW: 'add = uncurry (+)'. Si noti inoltre che la risposta 'zipWith' è il primo hit su [Hoogle] (http://haskell.org/hoogle/) per la query [' (a -> b -> c) -> \ [a \] - > \ [b \] -> \ [c \] '] (http://haskell.org/hoogle/?hoogle=%28a+-%3E+b+-%3E+c%29+-%3E+%5Ba% 5D + -% 3E +%% 5d 5BB + -% 3E +% 5Bc% 5D). – ephemient

+0

Grazie a Dio, proverò su Google la prossima volta. –

+0

@ TomMD, non capisco la prima parte del tuo commento. –

risposta

28

C'è una funzione zipWith libreria che unisce due liste utilizzando una funzione in dotazione. Fa esattamente quello che vuoi qui e si ottiene:

addLists = zipWith (+) 

Questo utilizza (+) di combinare gli elementi delle liste indicate come ulteriori argomenti.

+0

Mi ha picchiato. –

2
addLists xs ys = zipWith (+) xs ys 
6

stile applicativo Functor:

import Control.Applicative 

addLists xs ys = getZipList $ (+) <$> ZipList xs <*> ZipList ys 

Si noti che questo è così brutto, perché ci sono due modi per fare lista un applicativo Functor. Il primo (e IMHO meno utile) è prendere tutte le combinazioni, e in questo modo diventa lo "standard", quindi (+) <$> [1,2] <*> [30,40] è [31,41,32,42]. L'altro modo è di comprimere gli elenchi come necessario, ma poiché si può avere una sola istanza di classe di tipo per tipo, dobbiamo avvolgere gli elenchi in elenchi di zip e scartare il risultato utilizzando getZipList.

Problemi correlati