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

21
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, 3 rd Int.School of Advanced Functional Programming, 1998 Schémy rekurzie: catamorfizmus anamorfizmus hylomorfizmus

Upload: wattan

Post on 20-Mar-2016

45 views

Category:

Documents


3 download

DESCRIPTION

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 - PowerPoint PPT Presentation

TRANSCRIPT

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

Triedenie s banánmi, šošovkami a obálkamidnes 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

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

List-anamorfizmusana (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

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

ziplist_ana1 :: (b->Bool) -> (b -> (a,b)) -> b -> [a]

zip1 ([1,2,3],[11,22,33])[(1,11),(2,22),(3,33)]

Definujme zip1 :: ([x],[y]) -> [(x,y)] pomocou list_ana1:

ujasnime si typy...b = ([x],[y])a = (x,y)p :: ([x],[y]) -> Boolg :: ([x],[y]) -> ( (x,y) , ([x],[y]) )

zip1 :: ([x],[y]) -> [(x,y)]zip1 = list_ana1 p g where

p ([],_) = True -- True, ak končí rekuziap (_,[]) = Truep (_,_) = Falseg (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

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

iterate, mapDefinujte 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 gwhere p _ = False -- never ending...g a = (a,f a) -- a je prvok do výsledneho zoznamu-- (f a) je argument na rekurzívne volanie list_ana1

map1 f = list_ana1 p gwherep [] = Truep _ = Falseg (a:as) = (f a, as) -- f a je prvok do výsledneho zozn.-- as je argument na rekurzívne volanie list_ana1

list_ana1 :: (b->Bool) -> (b -> (a,b)) -> b -> [a]

take 10 (iterate1 (+1) 5)[5,6,7,8,9,10,11,12,13,14]

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

List-coalgebraEither 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 ofLeft _ -> [] -- vtedy končíme, lca u = Left _Right (a,b') -> a : ana b' -- lca u = Right (a,b’), t.j. g b = (a,b’)

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

List-coalgebradestruct_count 0 = Left () – kedy končímedestruct_count n = Right (n,n-1) – n ide do výsledku

– na n-1 ide rekurziacount :: Integer -> [Integer]count = list_ana2 destruct_count

iterate2 f = list_ana2 (\a -> Right (a,f a))

map2 f = list_ana2 destruct_list wheredestruct_list [] = Left ()destruct_list (a:as)= Right(f a, as)

list_ana2 :: List_coalg b a -> b -> [a]

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]

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

List-coalgebra’ – iná syntaxtype 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 ofTrue' -> []False' (a,b') -> a : ana b'

count' = list_ana2' destruct_countwheredestruct_count 0 = True'destruct_count n = False' (n,n-1)

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

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 wheredestruct_count 0 = Nothingdestruct_count n = Just (n,n-1)

iterate' f = unfoldr (\a -> Just (a, f a))

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

primeDefinujte prime ako anamorfizmusprime = sieve [2..] where

sieve = list_ana2 destruct_prime wheredestruct_prime (x:xs) = Right(x, [y | y <-xs, y `mod` x

> 0])

prime' = sieve [2..] wheresieve = 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.

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

insert-sortDefinujte insert-sort ako list-catamorfizmus (foldr)

insert_sort x = list_cata2 ([], insert) x whereinsert 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 []

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 ?

x:l

x l

x sort l

insert x (sort l)

destruct

recurse

insert

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

min-sort

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]

l

m l’

m sort l’

m:(sort l’)

extract minimum

recurse

construct

Cvičenie-4: Viete definovať remove ako list-cata resp. ana-morfizmus ?

Definujte min-sort ako list-anamorfizmus

selection_sort extract = list_ana2 select where

select [] = Left () select x= Right (extract x)-- dummy extract, prvyextra (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

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

buble-sortDefinujme buble_sort ako selection_sort

buble_sort ls = selection_sort extract_buble ls whereextract_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-morfizmusbuble_sort' ls = selection_sort extract_buble ls

whereextract_buble (x:ls) = list_cata2 ((x,[]), bub) lsbub x (y,ls) = if x < y then (x,y:ls) else (y,x:ls)

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]

l

m l’

m sort l’

m:(sort l’)

buble

recurse

construct

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

Hurá na stromy… aby sme objavili nelinearne patterny rekuzie

data LeafTree x = Leaf x | Node (LeafTree x) (LeafTree x) deriving(Show, Read, Eq)-- príklad rekurzietree_sum (Leaf x) = xtree_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 -> uleaftree_cata (fl, fs) = cata where

cata (Leaf x) = fl xcata (Node l r) = fs (cata l) (cata r)

– príkladtree_sum' = leaftree_cata (id,(+))

1

7 9

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

Ana na strometype Leaftree_coalg b a = b -> Either a (b,b)

leaftree_ana :: Leaftree_coalg b a -> b -> LeafTree aleaftree_ana lftca = ana where

ana t = case lftca t ofLeft l -> Leaf lRight (l,r)-> Node(ana l) (ana r)

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

Fib treefib_tree n

| n < 2 = Leaf 1| otherwise = Node (fib_tree (n-1)) (fib_tree (n-2))

– ako ana-morfizmusfib_tree' = leaftree_ana destruct_fib where

destruct_fib n | n < 2 = Left 1 | otherwise = Right (n-1, n-2)

fib_tree 4Node (Node (Node (Leaf 1) (Leaf 1)) (Leaf 1)) (Node (Leaf 1) (Leaf 1))

1

1 1

1 1

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

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 -> vleaftree_hylo (d, (fl, fs)) = hylo where

hylo t = case d t ofLeft l -> fl l -- (Leaf l) -> applikuj flRight (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.

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

List-hylomorfizmuslist_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.

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

merge-sortmerge_sort [] = []merge_sort xs = leaftree_hylo (select, (single, merge)) xs

wheresingle x = [x]merge (x:xs) (y:ys) | x < y = x:merge xs (y:ys)

| otherwise = y : merge (x:xs) ysmerge [] m = mmerge m [] = mselect [x] = Left xselect l = Right (split l)

split = list_cata2 (([],[]),f) wheref 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))

4 2 3 1

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

Binárny stromdata 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 -> ubintree_cata (a,f) = cata where

cata Nil = acata (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 xbintree_ana btca= ana where

ana t = case btca t ofLeft _ -> NilRight (x,l,r) -> Branch x (ana l) (ana r)

Cvičenie-8: Definujte bintree_hylo ako binarytree hylo-morfizmus.

3

1 8

7 9

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

quick-sortquick_sort l = bintree_hylo (split, ([], join)) l where

split [] = Left ()split (x:l) = Right (x, smaller, greater) where (smaller,greater) = partition' (<x) ljoin x l r = l ++ x : r

partition' p l = list_cata2 (([],[]),f) l wheref 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.

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

para-morfizmustype List_para x u = (u, x->[x]->u->u)

list_para :: List_para x u -> [x] -> ulist_para (a,f) = para where

para [] = apara (x:l) = f x l (para l)

insert'' x = list_para ([x],combine) wherecombine 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.