Haskell Lite mera om listor
Skapa en lista mha ett delintervall Prelude> [1..8] [1,2,3,4,5,6,7,8] Prelude> [ ] [1.1,2.1] Prelude> [ ] [1.1,2.1,3.1,4.1] Prelude> [1,3..10] [1,3,5,7,9] Steglängd: default 1 Sista elementet närmast slutgränsen Steglängd: default 1 Sista elementet närmast slutgränsen Du kan definiera steglängden själv implicit
Skapa en lista mha ett delintervall Prelude> [1.1, ] [1.1,1.2, , , , , , , , , , , , ] Inte så exakt när det gäller flyttal...
List comprehension En kraftfull mekanisk för att skapa listor Syntax (jfr matematisk standardnotation; <- ska tolkas som ∈ Prelude> let ex = [1..10] Prelude> ex [1,2,3,4,5,6,7,8,9,10] Prelude> let x2 = [2*x | x <- ex] Prelude> x2 [2,4,6,8,10,12,14,16,18,20]
List comprehension Du kan också använda funktioner i list comprehensions: Prelude> let isEven n = (n `mod` 2 == 0) Prelude> :info isEven isEven :: Integral a => a -> Bool -- Defined at :22:5 Prelude> let evenEx = [isEven x | x <- ex] ex = [1..10] Prelude> evenEx [False,True,False,True,False,True,False,True,False,True] Prelude> let evenEx = [isEven x | x <- x2] ex2 = [2,4..20] Prelude> evenEx [True,True,True,True,True,True,True,True,True,True]
List comprehension Du kan sätta villkor till generatorn: Prelude> let exBig = [x | x = 10] Prelude> exBig [10,12,14,16,18,20] Prelude> let ex = [1..100] Prelude> let testL = [x | x 60] Prelude> testL [62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100]
List comprehension Du kan använda ett mönster i stället för en variabel på den vänstra sidan av pilen: Prelude> let parPlus = [x+y | (x,y) <- [(1,1),(2,2),(4,4)]] Prelude> parPlus [2,4,8]
List comprehension Du kan ha två generatorer och kombinera deras resultat, här till en kartesisk produkt: Prelude> let paraxy = [(x,y) | x <- [1..5], y <- [1..5]] Prelude> paraxy [(1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,2),(2,3),(2,4),(2,5),(3,1),(3,2),(3,3),(3,4),(3,5),(4,1),(4,2),(4,3),(4,4),(4,5),(5,1),(5,2),(5,3),(5,4),(5,5)] Prelude> let testL = [x - y | x <- [1..5], y <- [2,4..10]] Prelude> testL [-1,-3,-5,-7,-9,0,-2,-4,-6,-8,1,-1,-3,-5,-7,2,0,-2,-4,-6,3,1,-1,-3,-5]
List comprehension Obs! Om du vill subtrahera elementen parvis, dvs första element – första element, andra element – andra element etc. finns det andra operationer för detta! (Se zip och zipWith) Prelude> let l1 = [1..5] Prelude> let l2 = [2,4..10] Prelude> :info zip zip :: [a] -> [b] -> [(a, b)] -- Defined in `GHC.List' Prelude> let l3 = zip l1 l2 Prelude> l3 [(1,2),(2,4),(3,6),(4,8),(5,10)] Prelude> let l4 = [a-b | (a,b) <- l3] Prelude> l4 [-1,-2,-3,-4,-5]
List comprehension Vi kan också göra detta ännu snyggare utan list comprehension när vi tittar mera på högre ordningens funktioner: Prelude> l1 [1,2,3,4,5] Prelude> l2 [2,4,6,8,10] Prelude> let l5 = zipWith (-) l1 l2 Prelude> l5 [-1,-2,-3,-4,-5]
List comprehension Vi kan använda list comprehension i funktionsdefinitioner: Prelude> let addOrdPairs pairList = [m+n | (m,n) <- pairList, m < n] Prelude> :info addOrdPairs addOrdPairs :: (Num t, Ord t) => [(t, t)] -> [t] -- Defined at :55:5 Prelude> addOrdPairs [(1,1), (1,2), (2,3), (4,2)] [3,5]
List comprehension Vi kan använda list comprehension i funktionsdefinitioner: Prelude> let allEven xs = (xs == [x | x <- xs, isEven x]) Prelude> :info allEven allEven :: Integral a => [a] -> Bool -- Defined at :58:5 Prelude> allEven [1..10] False Prelude> allEven [2,4..20] True Prelude> allEven [2,4..19] True 19 är ej med i listan!
List comprehension Vi kan använda list comprehension i funktionsdefinitioner: Prelude> let singletons xss = [x | [x] <- xss] Prelude> :info singletons singletons :: [[t]] -> [t] -- Defined at :63:5 Prelude> singletons [[], [1], [2], [3,4,5], [2,4], [6,7,8], [9]] [1,2,9] Observera hur mönsteranpassning används här!