Lijsten (met Map, Fold, Filter)
Intro Lists Coen
Typ op de command line
elm-repl
REPL staat voor ... (google hier eens op).
We kunnen nu elm expressies intypen die dan direct geëvalueerd worden. Bijvoorbeeld:
42
Reactie:
42 : number
ofwel repl heeft gezien dat het resultaat 42 is en dat dit een getal (number) is.
Iets spannender (denk even na of je het antwoord van deze vermeningvuldiging makkelijk zelf zou kunnen berekenen)
42 * 38
Hee, je kunt het dus als rekenmachine gebruiken... Enfin, je bent waarschijnlijk niet heel erg verbaasd.
Inderdaad kun je met +, -, * en / optellen, aftrekken, vermenigvuldigen en delen.
Wat denk je dat er uitkomt als je
12 + 3 * 2
intypt? Houdt elm rekening met de volgorde van berekening? Wordt eerst de + of eerst * uitgevoerd? Ofwel: is dit gelijk aan ( 12 + 3 ) * 2 of juist aan 12 + ( 3 * 2) ? 0.0.0.1. Reken
Als je zelf de volgorde wil aangeven kun je er voor kiezen op de volgende manier te rekenen:
add 12 ( multiply 3 2 )
Hierbij worden er 2 dingen opgeteld (add): het eerste is een getal, het andere is de uitkomst van de vermenigvuldiging van 3 en 2 (multiply).
Stel er zou staan:
multiply ( add 12 3 ) 2
dan zou juist de uitkomst van 12+3 vermenigvuldigd worden met 2.
Nu is add een functie die normaalgesproken 2 parameters krijgt, maar in de taal elm kun je de parameters 1 voor 1 aan een functie voeren. De combinatie add 2 is een optelfunctie die al weet dat ie 2+.. gaat doen.
Nu zijn add en multiply al bestaande functies. Je kunt ook zelf nieuwe functies erbij programmeren. Met bijvoorbeeld
telTweeOpBij x = x + 2
wordt een nieuwe functie telTweeOpBij (deze naam kun je dus zelf kiezen) gedefinieerd door de al genoemde add 2 constructie (deze combinatie ís ook weer een functie). Na deze definitie kun je schrijven
telTweeOpBij 5
Komt hier uit wat je verwacht? Onthoud de functie telTweeOpBij, we komen hier op terug. 0.0.0.2. List
Typ eens in:
List.range 1 9
Resultaat:
[1,2,3,4,5,6,7,8,9] : List Int
Hee, hoe komt dat? Blijkbaar wordt er een lijstje van getallen opgebouwd.
Ook kun je aan een bestaande List met behulp van :: een element toevoegen:
42 :: (List.range 1 9)
en ook meerdere elementen kan
83 :: 42 :: (List.range 1 9)
Zoals je ziet zijn haakjes hier niet nodig. Op deze manier kun je een bestaande List verlengen. 0.0.0.3. En tel er 2 bij op...
Het leuke van Lists is dat je er berekeningen op kunt gaan toepassen. Stel we willen bij elk getal in de List het getal 2 optellen. We mappen dan de functie telTweeOpBij op elk getal uit de List:
List.map telTweeOpBij (List.range 1 9)
We hadden in plaats van telTweeOpBij ook kunnen schrijven
List.map ( \x -> x + 2 ) (List.range 1 9)
waarbij x -> x + 2 eigenlijk wil zeggen: wat er in gaat noemen we x en er komt uit x + 2. Je kunt dit vergelijken met een functie f in de wiskunde
f(x) = x + 2
alleen heeft de functie x -> x + 2 geen naam. Bij de definitie van telTweeOpBij een stukje terug hadden we de functie wel een naam gegeven (namelijk telTweeOpBij). Herhalen we nu die definitie maar dan met naam f in plaats van telTweeOpBij dan staat er:
f x = x + 2
Hee, da's bijna wiskunde!? We hebben nu dus 2 manieren gezien om een functie te definiëren
f x = x + 2 \x -> x + 2
De eerste definieert functie f en de tweede heeft geen naam, is anoniem. We noemen die tweede definitie dan ook een anonymous function.
Enfin, de constructie
List.map ( \x -> x + 2 ) (List.range 1 9)
is niet super-leesbaar. Je mag dit in elm ook anders opschrijven: Neem (List.range 1 9) en map op elk element de functie ( x -> x + 2 ). Dit ziet er dan uit als:
(List.range 1 9) |> List.map ( \x -> x + 2 )
In de repl moet je op het eind van een regel een backslash (\) typen (die staat hier door) om op de volgende regel door te gaan.