Kihagyás

12. gyakorlat

sum' :: Num a => [a] -> a
sum' [] = 0
sum' (x:xs) = x + sum1 xs

product' :: Num a => [a] -> a
product' [] = 1
product' (x:xs) = x * product1 xsun

elem' :: Eq a => a -> [a] -> Bool
elem' a [] = True
elem' a (x:xs) = a == x || elem' a xs

hSum :: Num a => [Bool] -> a
hSum [] = 0
hSum (x:xs) = h x + hSum xs
    where
        h :: Num a => Bool -> a
        h True = 1
        h False = 0

Mit veszünk észre?

  • Mindegyikben van rekurzió
  • Üres lista és legalább egy elem esetei

Kb. lemásolhattuk volna a kódot => Általánosítsuk

foldr

-- r néven a foldr függvény

r :: (a -> b -> b) -> b -> [a] -> b
r f b [] = b
r f b (x:xs) = x `f` (r f b xs)


-- Ezt az általánosított függvényt felhasználva

sum2 :: Num a => [a] -> a
sum2 = r (+) 0

product2 :: Num a => [a] -> a
product2 = r (*) 1

elem2 :: Eq a => a -> [a]
elem2 a = r (\b acc -> a == b || acc) False


-- A (Birodalom helyett a) splitOn visszavág... megint. Utoljára?
splitOn :: Eq a => a -> [a] -> [[a]]
splitOn _ [] = [[]]
splitOn e (x:xs)
    | e == x = [] : splitOn e xs
    | otherwise = (x : head (spitOn e xs)) : tail (splitOn e xs)


-- Ha a splitOn olyan jó, miért nincs-
splitOn2 :: Eq a => a -> [a] -> [[a]]
splitOn2 e xs = r f [[]]
    where
        f x acc
            | e == x = [] : acc
            | otherwise = (x : head acc) : tail acc

foldl

-- l néven a foldl függvény

l :: (b -> a -> b) -> b -> [a] -> b
l f acc [] = []
l f acc (x:xs) = l (acc `f` x) xs 


reverse1 :: [a] -> [a]
reverse1 = h []
    where
        h acc [] = acc
        h acc (x:xs) = h (x:acc) xs


reverse2 :: [a] -> [a]
--reverse2 = l (\acc x -> x:acc) []
reverse2 = l (flip (:)) []