Kihagyás

6. gyakorlat

Lokálisan definiált függvények

  • where
  • let ... in

Mire jó?

  • Lokális függvény definiálása (pl. segédfüggvénynek)
  • Accumulator használata

Accumulator

Példa: reverse

-- a very slow version
reverse' :: [a] -> [a]
reverse' [] = []
reverse' (x:xs) = reverse' xs ++ [x]
reverse'' :: [a] -> [a]
reverse'' [] = []
reverse'' xs = reverseAcc xs []
    where
        reverseAcc [] acc = acc
        reverseAcc (y:ys) acc = reverseAcc ys (y:acc)

Ez ugyanaz, csak másképp:

reverse''' :: [a] -> [a]
reverse''' [] = []
reverse''' xs = 
    let 
        reverseAcc [] acc = acc
        reverseAcc (y:ys) acc = reverseAcc ys (y:acc)
    in
        reverseAcc xs []

Mi történik?

reverseAcc [1, 2, 3] []
reverseAcc [2, 3] [1]
reverseAcc [3] [2, 1]
reverseAcc [] [3, 2, 1]

Példa: length

length :: [a] -> Int
length list = acc 0 list
    where
        acc :: Int -> [a] -> Int
        acc n [] = n -- You're at the end
        acc n (_:xs) = acc (n + 1) xs

Mi történik?

acc 0 [1, 2, 3, ... n]
acc 1 [2, 3, ... n]
acc 2 [3, ... n]

...

acc n [] = n

Segéd függvény

Példa: splitAt

Függvény definiálása lokálisan (pl. segédfüggvénynek)

splitAt' :: Integral i => i -> [a] -> ([a],[a])
splitAt' _ [] = ([],[])
splitAt' n xs | n <= 0 = ([], xs)
splitAt' n (x:xs) = (x:a,b)
    where
        (a,b) = splitAt' (n-1) xs

Példa: unzip

unzip' :: [(a,b)] -> ([a], [b])
unzip' [] = []
unzip' [(a,b):xs] = (a:as,b:bs)
    where
        (as, bs) = unzip' xs

Lambdák

Névtelen függvény

Szintaxis:

(\ paraméterek -> kifejezés)
f :: Num a => a -> a
f alma = alma * 2

f' = (\alma -> alma * 2) -- u.a. mint az `f`

Magasabb rendű függvény: olyan függvény, amelynek a paramétere is függvény