Recherche…


Compréhension de la liste de base

Haskell a des compréhensions de listes , qui ressemblent beaucoup à des compréhensions d'ensemble en mathématiques et à des implémentations similaires dans des langages impératifs tels que Python et JavaScript. Dans leur forme la plus simple, les compréhensions de liste prennent la forme suivante.

[ x | x <- someList ]

Par exemple

[ x | x <- [1..4] ]    -- [1,2,3,4]

Les fonctions peuvent aussi être appliquées directement à x:

[ f x | x <- someList ]

Ceci est équivalent à:

map f someList

Exemple:

[ x+1 | x <- [1..4]]    -- [2,3,4,5]

Motifs dans les expressions du générateur

Cependant, x dans l'expression du générateur n'est pas seulement variable, mais peut être n'importe quel modèle. En cas de non concordance de modèle, l'élément généré est ignoré et le traitement de la liste continue avec l'élément suivant, agissant ainsi comme un filtre:

[x | Just x <- [Just 1, Nothing, Just 3]]     -- [1, 3]

Un générateur avec une variable x dans son modèle crée une nouvelle étendue contenant toutes les expressions à sa droite, où x est défini comme étant l'élément généré.

Cela signifie que les gardes peuvent être codés comme

[ x | x <- [1..4], even x] ==
[ x | x <- [1..4], () <- [() | even x]] ==
[ x | x <- [1..4], () <- if even x then [()] else []]

Gardes

Une autre caractéristique de la compréhension de liste est celle des gardes, qui servent également de filtres. Les gardes sont des expressions booléennes et apparaissent sur le côté droit de la barre dans une liste de compréhension.

Leur utilisation la plus élémentaire est

[x    | p x]   ===   if p x then [x] else []

Toute variable utilisée dans un garde doit apparaître à sa gauche dans la compréhension ou être dans la portée. Alors,

[ f x | x <- list, pred1 x y, pred2 x]     -- `y` must be defined in outer scope

ce qui équivaut à

map f (filter pred2 (filter (\x -> pred1 x y) list))          -- or,

-- ($ list) (filter (`pred1` y) >>> filter pred2 >>> map f)     

-- list >>= (\x-> [x | pred1 x y]) >>= (\x-> [x | pred2 x]) >>= (\x -> [f x])

(l'opérateur >>= est infixl 1 , c'est-à-dire qu'il est associé (est mis entre parenthèses) à gauche). Exemples:

[ x       | x <- [1..4], even x]           -- [2,4]

[ x^2 + 1 | x <- [1..100], even x ]        -- map (\x -> x^2 + 1) (filter even [1..100])

Générateurs imbriqués

Les compréhensions de listes peuvent également dessiner des éléments de plusieurs listes, auquel cas le résultat sera la liste de toutes les combinaisons possibles des deux éléments, comme si les deux listes étaient traitées de manière imbriquée . Par exemple,

[ (a,b) | a <- [1,2,3], b <- ['a','b'] ]

-- [(1,'a'), (1,'b'), (2,'a'), (2,'b'), (3,'a'), (3,'b')]

Compréhensions parallèles

Avec l'extension de langage Parallel List Comprehensions ,

[(x,y) | x <- xs | y <- ys]

est équivalent à

zip xs ys

Exemple:

[(x,y) | x <- [1,2,3] | y <- [10,20]] 

-- [(1,10),(2,20)]

Liaisons locales

Les compréhensions de liste peuvent introduire des liaisons locales pour les variables afin de contenir certaines valeurs intermédiaires:

[(x,y) | x <- [1..4], let y=x*x+1, even y]    -- [(1,2),(3,10)]

Le même effet peut être obtenu avec une astuce,

[(x,y) | x <- [1..4], y <- [x*x+1], even y]   -- [(1,2),(3,10)]

La let dans la liste compréhensions est récursive, comme d' habitude. Mais les liaisons de générateur ne le sont pas, ce qui permet l' observation :

[x | x <- [1..4], x <- [x*x+1], even x]       -- [2,10]

Notation

Toute compréhension de liste peut être en correspondance codé avec la liste monade de do notation .

[f x | x <- xs]                 f  <$> xs         do { x <- xs ; return (f x) }

[f x | f <- fs, x <- xs]        fs <*> xs         do { f <- fs ; x <- xs ; return (f x) }

[y   | x <- xs, y <- f x]       f  =<< xs         do { x <- xs ; y <- f x ; return y }

Les gardes peuvent être manipulés en utilisant Control.Monad.guard :

[x   | x <- xs, even x]                           do { x <- xs ; guard (even x) ; return x }


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow