2011-01-23 3 views
10

Supposons que je souhaite ajouter deux listes dans Haskell. Quelle est la manière la plus courante de le faire?Qu'est-ce qu'une façon idiomatique d'ajouter des listes dans Haskell?

Voici ce que je l'ai fait:

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

BTW: 'add = uncurry (+)'. Notez également que la réponse 'zipWith' est le premier hit sur [Hoogle] (http://haskell.org/hoogle/) pour la requête [' (a -> b -> c) -> \ [a \] - > \ [b \] -> \ [c \] '] (http://haskell.org/hoogle/?hoogle=%28a+-%3E+b+-%3E+c%29+-%3E+%5Ba% 5D + -% 3E +% 5Bb% 5d + -% 3E +% 5Bc% 5D). – ephemient

+0

Merci ephemient, je vais essayer d'abord Hoogle la prochaine fois. –

+0

@ TomMD, je ne comprends pas la première partie de votre commentaire. –

Répondre

28

Il y a une fonction de bibliothèque zipWith qui combine deux listes en utilisant une fonction fournie. Il fait exactement ce que vous voulez ici et vous obtenez:

addLists = zipWith (+) 

Il utilise (+) pour combiner les éléments des listes données que d'autres arguments.

+0

Aw me battre à elle. –

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

de style Applicative Functor:

import Control.Applicative 

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

Notez que cela est si laid parce qu'il ya deux façons de faire une liste Applicative Functor. La première (et à mon avis moins utile) est de prendre toutes les combinaisons, et de cette façon est devenu le « standard », donc (+) <$> [1,2] <*> [30,40] est [31,41,32,42]. L'autre façon est de compresser les listes comme nous en avons besoin ici, mais comme vous ne pouvez avoir qu'une seule instance de type par type, nous devons envelopper les listes dans ZipLists, et déplier le résultat en utilisant getZipList.

Questions connexes