1 / 21

Triedenie s banánmi, šošovkami a obálkami

Triedenie s banánmi, šošovkami a obálkami. d nes u ž k triedeniu príde... Erik Meijer, Maarten Fokkinga, Ross Paterson: Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire

wattan
Download Presentation

Triedenie s banánmi, šošovkami a obálkami

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Triedenie s banánmi, šošovkami a obálkami dnes už k triedeniu príde... • Erik Meijer, Maarten Fokkinga, Ross Paterson: Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire • Lex Augusteijn: Sorting morfizmuss, LNCS 1608, 3rd Int.School of Advanced Functional Programming, 1998 • Schémy rekurzie: • catamorfizmus • anamorfizmus • hylomorfizmus

  2. List-anamorfizmus ana (upwards as anabolismus) anamorfizmus alias lenses[( )], unfold list-anamorfizmus je funkcia typu b -> [a]: • deštruuj b, • komponenty typu U rekurzívne konvertuj do [a], • skombinuj výsledky typu [a] do výsledku typu [a]. list_ana1 :: (b->Bool) -> (b -> (a,b)) -> b -> [a] list_ana1 p g b | p b = [] -- ak p b, tak končí rekuzia (terminátor) | otherwise = a:list_ana1 p g b' where (a,b') = g b-- g je nextor -- a je prvok do výsledného zoznamu -- b' je argument na rekurzívne volanie list_ana1

  3. zip list_ana1 :: (b->Bool) -> (b -> (a,b)) -> b -> [a] Definujme zip1 :: ([x],[y]) -> [(x,y)] pomocou list_ana1: ujasnime si typy... b = ([x],[y]) a = (x,y) p :: ([x],[y]) -> Bool g :: ([x],[y]) -> ( (x,y) , ([x],[y]) ) zip1 :: ([x],[y]) -> [(x,y)] zip1 = list_ana1 p g where p ([],_) = True -- True, ak končí rekuzia p (_,[]) = True p (_,_) = False g (a:as, b:bs) = ((a,b), (as,bs)) -- (a,b) je prvok do výsledneho zoznamu -- as,bs je argument na rekurzívne volanie list_ana1 zip1 ([1,2,3],[11,22,33]) [(1,11),(2,22),(3,33)]

  4. iterate, map list_ana1 :: (b->Bool) -> (b -> (a,b)) -> b -> [a] Definujte iterate1 :: (x -> x) -> x -> [x] pomocou list_ana1, aby iterate1 f a = [a, f a, f f a, f f f a, ...] ujasnime si typy: • b = a = x • p :: (x -> Bool) - terminátor • g :: x -> (x,x) - nextor iterate1 f = list_ana1 p g where p_ = False -- never ending... g a = (a,f a)-- a je prvok do výsledneho zoznamu -- (f a) je argumentna rekurzívne volanie list_ana1 map1 f = list_ana1 p g where p [] = True p _ = False g (a:as) = (f a, as)-- f a je prvok do výsledneho zozn. -- as je argumentna rekurzívne volanie list_ana1 take 10 (iterate1 (+1) 5) [5,6,7,8,9,10,11,12,13,14]

  5. List-coalgebra Either je súčet typov (union type) s tagmi Left a Right: • data Either a b = = Left a | Right b type List_coalg b a = b -> Either () (a, b) -- dosadíme Left () | Right (a, b) List_coalg je p(terminátor) aj g (nextor) dokopy: • ak list_coalg b = Left _, tak p b = True, • ak list_coalg b = Right(a, b'), tak (a, b') = g b list_ana2 :: List_coalg b a -> b -> [a] list_ana2 lca = ana where ana u = case lca u of Left _ -> [] -- vtedy končíme, lca u = Left _ Right (a,b') -> a : ana b' -- lca u = Right (a,b’), t.j. g b = (a,b’)

  6. List-coalgebra list_ana2 :: List_coalg b a -> b -> [a] destruct_count 0 = Left ()– kedy končíme destruct_count n = Right (n,n-1) – n ide do výsledku – na n-1 ide rekurzia count :: Integer -> [Integer] count = list_ana2 destruct_count iterate2 f = list_ana2 (\a -> Right (a,f a)) map2 f = list_ana2 destruct_list where destruct_list [] = Left () destruct_list (a:as)= Right(f a, as) count 5 [5,4,3,2,1] take 10 (iterate2 (+1) 0) [0,1,2,3,4,5,6,7,8,9] map2 (+1) [1..10] [2,3,4,5,6,7,8,9,10,11]

  7. List-coalgebra’ – iná syntax type List_coalg b a = b -> Either () (a, b) ==== b -> Left () | Right (a,b) data Either' x = True' | False' x – predefinujem náš vlastný Either type List_coalg' b a = b -> Either' (a, b) type List_coalg' b a = b -> Either' (a, b) = b -> True' | False' (a,b) list_ana2' :: List_coalg' b a -> b -> [a] list_ana2' lca = ana where ana u = case lca u of True' -> [] False' (a,b') -> a : ana b' count' = list_ana2' destruct_count where destruct_count 0 = True' destruct_count n = False' (n,n-1)

  8. unfoldr (List.hs) data Either' x = True' | False' x data Maybe a = Nothing | Just a– v haskelli, Prelude.hs deriving (Eq, Ord, Read, Show) unfoldr :: (b -> Maybe (a, b)) -> b -> [a] unfoldr f b = case f b of Just (a,b’) -> a : unfoldr f b’ Nothing -> [] count'' = unfoldr destruct_count where destruct_count 0 = Nothing destruct_count n = Just (n,n-1) iterate' f = unfoldr (\a -> Just (a, f a))

  9. prime Definujte prime ako anamorfizmus prime = sieve [2..] where sieve = list_ana2 destruct_prime where destruct_prime (x:xs) = Right(x, [y | y <-xs, y `mod` x > 0]) prime' = sieve [2..] where sieve = list_ana2 ' destruct_prime where destruct_prime (x:xs) = False'(x, [y | y <-xs, y `mod` x > 0]) take 100 prime [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,...] Cvičenie-1: Definujte [1,2,4,8,...,2n, ...] ako anamorfizmus. Cvičenie-2: Definujte [1,3,7,15,..., 2n-1, ...] ako anamorfizmus. Cvičenie-3: Definujte [1,2, 6, 24,..., n!, ...] ako anamorfizmus.

  10. x:l insert-sort destruct x l recurse Definujte insert-sort ako list-catamorfizmus (foldr) insert_sort x = list_cata2 ([], insert) x where insert a [] = [a] insert a (x:xs) | a < x = a:x:xs | otherwise = x : insert a xs insert :: Int -> [Int] -> [Int] -- inak, cez foldr insert_sort' :: [Int] -> [Int] insert_sort' = foldr insert [] x sort l insert insert x (sort l) insert_sort [2,2,1,34,5,2,4,23,2,4] [1,2,2,2,2,4,4,5,23,34] Cvičenie-4: Viete definovať insert ako list-cata resp. ana-morfizmus?

  11. l min-sort extract minimum m l’ recurse Definujte min-sort ako list-anamorfizmus selection_sort extract = list_ana2 select where select [] = Left () select x = Right (extract x) -- dummy extract, prvy extra (x:xs) = (x,xs) min_sort xs = selection_sort extract_min xs where extract_min ls = (m, remove m ls) where m = minimum ls remove x [] = [] remove x (y:ls) | x == y = ls | otherwise = y : remove x ls m sort l’ construct m:(sort l’) selection_sort extra [4,3,2,4,2,1,3] [4,3,2,4,2,1,3] min_sort [4,3,2,4,2,1,3] [1,2,2,3,3,4,4] Cvičenie-4: Viete definovaťremove ako list-cata resp. ana-morfizmus?

  12. l buble-sort buble m l’ recurse Definujme buble_sort ako selection_sort buble_sort ls = selection_sort extract_buble ls where extract_buble [x] = (x, []) extract_buble (x:ls) = if x < y then (x,y:m) else (y,x:m) where (y,m) = extract_buble ls -- definujme extract_buble ako cata-morfizmus buble_sort' ls = selection_sort extract_buble ls where extract_buble (x:ls) = list_cata2 ((x,[]), bub) ls bub x (y,ls) = if x < y then (x,y:ls) else (y,x:ls) m sort l’ construct m:(sort l’) buble_sort [4,3,2,4,2,1,3] [1,2,2,3,3,4,4] buble_sort' [4,3,2,4,2,1,3] [1,2,2,3,3,4,4]

  13. Hurá na stromy 1 … aby sme objavili nelinearne patterny rekuzie data LeafTree x = Leaf x | Node (LeafTree x) (LeafTree x) deriving(Show, Read, Eq) -- príklad rekurzie tree_sum (Leaf x) = x tree_sum (Node l r) = tree_sum l + tree_sum r type Leaftree_alg x u = (x -> u, u -> u -> u) leaftree_cata :: Leaftree_alg x u -> LeafTree x -> u leaftree_cata(fl, fs) = cata where cata (Leaf x) = fl x cata (Node l r) = fs (cata l) (cata r) – príklad tree_sum' = leaftree_cata (id,(+)) 7 9

  14. Ana na strome type Leaftree_coalg b a = b -> Either a (b,b) leaftree_ana :: Leaftree_coalg b a -> b -> LeafTree a leaftree_ana lftca = ana where ana t = case lftca t of Left l -> Leaf l Right (l,r)-> Node(ana l) (ana r)

  15. Fib tree 1 1 1 fib_tree n | n < 2 = Leaf 1 | otherwise = Node (fib_tree (n-1)) (fib_tree (n-2)) – ako ana-morfizmus fib_tree' = leaftree_ana destruct_fib where destruct_fib n | n < 2 = Left 1 | otherwise = Right (n-1, n-2) 1 1 fib_tree 4 Node (Node (Node (Leaf 1) (Leaf 1)) (Leaf 1)) (Node (Leaf 1) (Leaf 1))

  16. Hylo-morfizmus (ana . cata) type Leaftree_hylo u x v = (Leaftree_coalg u x, Leaftree_alg x v) leaftree_hylo :: Leaftree_hylo u x v -> u -> v leaftree_hylo (d, (fl, fs)) = hylo where hylo t = case d t of Left l -> fl l -- (Leaf l) -> applikuj fl Right (l,r) -> fs (hylo l) (hylo r) -- (Node l r) -> applikuj fs fib = tree_sum' . fib_tree' fib' = leaftree_hylo (destruct_fib, (id, (+))) Cvičenie-5: Definujte n! ako leaftree hylo-morfizmus. Cvičenie-6: Definujte xn ako leaftree hylo-morfizmus.

  17. List-hylomorfizmus list_hylo1 a c = (list_cata2 c) . (list_ana2 a) prod = list_cata2 (1, (*)) fact3 = (list_cata2 (1, (*))) . (list_ana2 destruct_count) fact3' = prod . count fact3'' = list_hylo1 destruct_count (1, (*)) Cvičenie-7: Definujte xn ako list hylo-morfizmus.

  18. merge-sort 4 2 3 1 merge_sort [] = [] merge_sort xs = leaftree_hylo (select, (single, merge)) xs where single x = [x] merge (x:xs) (y:ys) | x < y = x:merge xs (y:ys) | otherwise = y : merge (x:xs) ys merge [] m = m merge m [] = m select [x] = Left x select l = Right (split l) split = list_cata2 (([],[]),f) where f x (l,r) = (r, x:l) split [1..10] ([2,4,6,8,10],[1,3,5,7,9]) leaftree_ana select [1..4] Node (Node (Leaf 4) (Leaf 2)) (Node (Leaf 3) (Leaf 1))

  19. Binárny strom 3 1 8 data BinaryTree x = Nil | Branch x (BinaryTree x) (BinaryTree x) type BinaryTree_alg x u = (u, x->u->u->u) bintree_cata :: BinaryTree_alg x u -> BinaryTree x -> u bintree_cata (a,f) = cata where cata Nil = a cata (Branch x l r) = f x (cata l) (cata r) type BinaryTree_coalg u x = u->Either () (x,u,u) bintree_ana :: BinaryTree_coalg u x -> u -> BinaryTree x bintree_ana btca= ana where ana t = case btca t of Left _ -> Nil Right (x,l,r) -> Branch x (ana l) (ana r) Cvičenie-8: Definujte bintree_hylo ako binarytree hylo-morfizmus. 7 9

  20. quick-sort quick_sort l = bintree_hylo (split, ([], join)) l where split [] = Left () split (x:l) = Right (x, smaller, greater) where (smaller,greater) = partition' (<x) l join x l r = l ++ x : r partition' p l = list_cata2 (([],[]),f) l where f x (a, b) = if p x then (x:a,b) else (a,x:b) Cvičenie-9: Cvičenie-10: Definujte n! ako bintree hylo-morfizmus. Cvičenie-11: Definujte xn ako bintree hylo-morfizmus. Cvičenie-12: Definujte hanojské veže ako bintree hylo-morfizmus.

  21. para-morfizmus type List_para x u = (u, x->[x]->u->u) list_para :: List_para x u -> [x] -> u list_para (a,f) = para where para [] = a para (x:l) = f x l (para l) insert'' x= list_para ([x],combine) where combine a l rec | x < a = x:a:l | otherwise = a:rec insert_sort'' x = list_cata2 ([], insert'') x Cvičenie-13: Definujte remove ako list para-morfizmus.

More Related