Haskell Hero
Interaktivní učebnice pro začínající Haskellisty
|
Seznamy IIHromadný výčet
Doposud jsme seznamy zapisovali běžným vypsáním jednotlivých prvků. Tzn. když jsme potřebovali seznam celých čísel od jedné do pěti, zapsali jsme jej takto:
Seznam čísel od jedné do pěti zapíšeme Příklady
[1..10] ~>* [1,2,3,4,5,6,7,8,9,10] [10..] = [10,11,12,13,14,15, ... ] take 3 [10..] ~>* [10,11,12] [20..10] ~>* [] ['a'..'f'] ~>* "abcdef"
Dále by se nám určitě hodil seznam všech lichých čísel od jedné do desíti. Ten zapíšeme následovně:
Pokud je Příklady
[1,3..10] ~>* [1,3,5,7,9] [10,20..] = [10,20,30,40,50 ... ] [1,2..0] ~>* [] [10,9..1] ~>* [10,9,8,7,6,5,4,3,2,1] [10,9..20] ~>* [] ['f','d'..'a'] ~>* "fdb" ['&','&'..] = "&&&&&&&&&&&& ... " Intenzionální zápisPříkladVytvořte rostoucí seznam všech čísel od jedné do milionu, která jsou buď sudá nebo dělitelná pěti. Z matematiky víme, jak bychom zapsali množinu čísel splňující zadané podmínky: { x | x je z množiny {1,..., 1000000}, x je sudé nebo x je dělitelné pěti}V Haskellu je zápis velice podobný: [ x | x <- [1..1000000], even x || x `mod` 5 == 0]Jak bude probíhat vyhodnocení takového výrazu? Hugs postupně projde všechny prvky ze seznamu [1..1000000] a každý otestuje, zda vyhovuje podmínce
even x || x `mod` 5 == 0Pokud vyhoví, přidá se do výsledného seznamu. Pokud nevyhoví, testuje se další prvek.
Konstrukci Co když se nám v zápise objeví generátorů více? Uveďme si krátký příklad: [ (x,y) | x <- [1..3], y <- [1..x] ]Jak bude vypadat vyhodnocení tohoto seznamu?
Výsledný seznam tedy bude vypadat následovně: [ (1,1), (2,1), (2,2), (3,1), (3,2), (3,3) ]Podobně by vyhodnocení vypadalo, kdyby se generovalo ze tří generátorů. Další příklady
[ 2*x | x <- [1..5] ] ~>* [2,4,6,8,10] map f s = [ f x | x <- s ] filter p s = [ x | x <- s, p x ] |