Naar inhoud springen

Lijstcomprehensie

Uit Wikipedia, de vrije encyclopedie

In programmeertalen is lijstcomprehensie een syntactische constructie om een lijst te noteren. Het is gebaseerd op de wiskundige notatie voor verzamelingen. Een lijstcomprehensie is syntactische suiker aangezien hetzelfde ook op een andere manier kan worden geprogrammeerd, zoals met de hogere-ordefuncties map en filter. Enkele programmeertalen waarin men lijstcomprehensie kan gebruiken zijn Python en Haskell.

Het is in de wiskunde mogelijk een verzameling als volgt te noteren:

Dit kan worden gelezen als: ' is de verzameling van alle producten '2 maal ', waarvoor geldt dat een element is van de verzameling natuurlijke getallen en dat in het kwadraat groter is dan 10'.

Deze notatie bevat de volgende onderdelen:

  • : een functie die op alle elementen wordt toegepast.
  • : een variabele die wordt gebruikt om de elementen van de verzameling te benoemen.
  • : de verzameling die als invoer dient.
  • : een predicaat dat moet gelden voor de elementen die in de verzameling komen.

In de functionele programmeertaal Haskell kan het bovenstaande geschreven worden als:

[ 2 * x | x <- [0..], x * x > 10 ]

Hierin staat [0..] voor de lijst natuurlijke getallen. Het gedeelte x <- [0..] wordt een generator genoemd.

De bovenstaande lijstcomprehensie kan ook als volgt worden genoteerd:

map (\x -> 2 * x) (filter (\x -> x * x > 10) [0..])

Het is ook mogelijk meer generatoren en meer predicaten te gebruiken, zoals:

[ (x, y) | x <- [1..10], x `rem` 3 == 0, y <- [1..10], x + y == 7 ]

Syntactische suiker

[bewerken | brontekst bewerken]

Lijstcomprehensie is een vorm van syntactische suiker aangezien de code ervoor ook in bestaande taalconstructies kan worden uitgedrukt. Voor de programmeertaal Haskell beschrijft het Haskell 98 Report[1] een systematische manier om lijstcomprehensies om te schrijven naar bestaande taalconstructies, zoals let ... in ... en if ... then ... else ....

Zo wordt [ x | x <- [0..], x `rem` 2 == 0 ] bijvoorbeeld omgeschreven naar:

let ok x = if x `rem` 2 == 0 then [x] else []
    ok _ = []
in concatMap ok [0..]

Hierin is rem een functie die de rest van een deling oplevert. De functie concatMap ok [0..] is hetzelfde als concat (map ok [0..]), waarbij map de functie map is en concat de concatenatie van een lijst.