Aritmetikk:
Ikke uventet kan vi gjøre aritmetiske operasjoner med Haskell. Skriv inn et gyldig aritmetisk uttrykk og trykk enter.
Hugs> 1+2+3 6 :: Integer
|
Hugs> sqrt 2 1.4142135623731 :: Double
|
Hugs> pi 3.14159265358979 :: Double
|
Hugs> 10/0 1.#INF :: Double
|
Vi ser i eksempelene over at Haskell Interpreteren gir oss svaret, samt hvilken type den har interferensert svaret til. Mer om typer og inferens senere.
Par, tripletter, tupler:
Paranteser brukes for å gruppere verdier av samme type. To verdier er et par, tre er en triplett, og n verdier er en n-tuple.
Hugs> (0,0) (0,0) :: (Integer,Integer)
Par med Integers.
|
Hugs> ('a','b') ('a','b') :: (Char,Char)
Par med Characters, merk ''.
|
Hugs> ("ab","cd") ("ab","cd") :: ([Char],[Char])
Par med Characterlister, d.v.s streng, merk "".
|
Hugs> ('a','b', 'c', 'd') ('a','b','c','d') :: (Char,Char,Char,Char)
En tuple med Characters, merk ''.
|
Vi ser noen tupler og hvordan Haskell Interpreteren interferer typene. Vi kan ha alle gyldige typer i en tupel.
Vi har noen innebygde funksjoner som virker på par. fst (first) og snd (second). Merk at verdiene i et par ikke trenger å være av samme type. Dette gjelder alle tupler.
Hugs> fst (0, 1) 0 :: Integer |
Hugs> snd (0,1) 1 :: Integer |
Hugs> fst ("string", 0) "string" :: [Char] |
snd (0, 'a') 'a' :: Char |
Dersom du prøver disse funksjonene på annet en par vil du få en feilmelding fra Interpreteren.
Oppgave: Skriv en funksjon som returnerer 4 fra tuplet: (('a',4),"string")?
Løsning:
Hugs> snd (fst(('a',4),"string"))
4 :: Integer
|
Lister:
I motsetning til par, tripletter og tupler kan lister inneholde et ubegrenset antall elementer. Men lister krever derimot at alle elementer i listen er av samme type.
Hugs> [0,1,2,3] [0,1,2,3] :: [Integer]
Liste med Integers.
|
Hugs> ['a','b','c','d'] "abcd" :: [Char]
Liste med Characters. D.v.s en streng.
|
Hugs> ["ab","cd","ef","gh"] ["ab","cd","ef","gh"] :: [[Char]]
Liste med strenger.
|
Hugs> [] [] :: [a]
Den tomme listen.
|
Lister defineres ved hjelp av [ ] (eng:square brackets). Tupler ble definert ved hjelp av ( ) (eng:paranthesis).
Vi konstruerer lister ved hjelp av operatoren con / : (tenk: construct) og den tomme listen.
Hugs> 'a' : 'b' : 'c' : [] "abc" :: [Char] |
Hugs> 1 : 2 : 3 : [1,2,3] :: [Integer] |
Hugs> True : False : [] [True,False] :: [Bool] |
Hugs> [] : [] [[]] :: [[a]] |
Noen definerte funksjoner på lister.
Hugs> length [1,2,3] 3 :: Int |
Hugs> head[1,2,3] 1 :: Integer |
Hugs> tail[1,2,3] [2,3] :: [Integer] |
Length: Returnerer lengden på listen. D.v.s antall elementer som er i listen.
Head: Returnerer første elementet i listen.
Tail: Returnerer alt utenom første elementet i listen.
Som nevnt lenger oppe er en streng i Haskell en liste med karakterer.
Hugs> ['h','e','i'] "hei" :: [Char] |
Hugs> 'h':'e':'i':[] "hei" :: [Char] |
Vi konkatinerer (setter sammen) lister med ++ operatoren.
Hugs> "Hei " ++ "verden" "Hei verden" :: [Char] |
Konverter string til numeriske verdier.
read "1" + 2 3 :: Integer |
Hugs> read "1" + read "2" 3 :: Integer |
Konverter numeriske verdier til string.
Hugs> "en plus to er lik " ++ show 3 "en plus to er lik 3" :: [Char] |
Bruk en funksjon på alle elementer v.h.a listefunksjonen map. Map tar inn en funksjon, samt en liste med verdier og anvender den gitte funksjonen på alle elementer i listen. Merk at når vi mapper over en liste vil lengden på innlisten og utlisten være like. Vi endrer kun selve elementene i listen.
Char> map toUpper "hei verden" "HEI VERDEN" :: [Char] |
Char> map toLower "Hei Verden" "hei verden" :: [Char] |
Om du bruker en standard WinHugs implementasjon er det mulig du må laste modulen Char for å få tilgang til toUpper / toLower.
Char> :load Char
Hugs session for: file:{Hugs}\packages\hugsbase\Hugs\Prelude.hs file:{Hugs}\packages\base\Prelude.hs file:{Hugs}\packages\hugsbase\Hugs.hs file:{Hugs}\packages\hugsbase\Hugs\Char.hs file:{Hugs}\packages\base\Data\Char.hs file:{Hugs}\packages\haskell98\Char.hs Char> |
Vi kan filtrere ut elementer i en liste ved å bruke listefunksjonen filter.
Char> filter isUpper "FJERN meg" "FJERN" :: [Char] |
Char> filter isLower "FJERN meg" "meg" :: [Char] |
Vi kan gjøre operasjoner mellom alle elementene i en liste ved å bruke listefunksjonen foldr / foldl. Denne funksjonen tar tre argumenter: en funksjon, en start verdi og en liste.
foldr (+) 0 [1, 2, 3] 6 :: Integer
0+(1+2+3 )= 6.
|
foldr (*) 1 [1, 2, 3] 6 :: Integer
1*(1*2*3) = 6
|
Merk at vi i (*) eksempelet har satt 1 som start verdi istedenfor 0. Dette fordi 0*(1*2*3) blir 0, og dermed ikke det svaret vi er ute etter.
Ved å bruke foldr går vi ut ifra at uttrykket som skal evalueres er høyre assosiativt. Men dette er ikke alltid tilfelle, f.eks ved subtraksjon ( - ).
foldr (-) 1 [4,8,5] 0 :: Integer |
foldl (-) 1 [4,8,5] -16 :: Integer |
Vi kan bruke foldl for å assosiere uttrykket mot venstre som vist i eksempelet over.
Merk at foldr evaluerer uttrykket forløpende og kan derfor i teorien brukes på uendelige lister, mens foldl evaluerer v.h.a en rekursiv stabel, og en vil derfor kun få resultat på endelige mengder.
foldr (-) 1 [4,8,5] ==> 4 - (foldr (-) 1 [8,5]) ==> 4 - (8 - foldr (-) 1 [5]) ==> 4 - (8 - (5 - foldr (-) 1 [])) ==> 4 - (8 - (5 - 1)) ==> 4 - (8 - 4) ==> 4 - 4 ==> 0 |
foldl (-) 1 [4,8,5] ==> foldl (-) (1 - 4) [8,5] ==> foldl (-) ((1 - 4) - 8) [5] ==> foldl (-) (((1 - 4) - 8) - 5) [] ==> ((1 - 4) - 8) - 5 ==> ((-3) - 8) - 5 ==> (-11) - 5 ==> -16 |
Da avslutter vi denne artikkelen her, og gleder oss til neste artikkel kommer. Da skal vi se litt på hvordan vi kan utvide mulighetene våre ved å programmere egne funksjoner, legge de i en ekstern fil som vi laster inn i Interpreteren.