infixr 0 $! ($!) :: (a->b) -> a -> b f $! x =... interni, pro striktni vyhodnocovani -- vyhodnoti top konstruktor x -}

Podobné dokumenty
Programovací í jazyk Haskell

Programovací jazyk Haskell

IB015 Neimperativní programování. Seznamy, Typy a Rekurze. Jiří Barnat Libor Škarvada

Definice uživatelského typu. Uživatelem definované typy. Součinové datové typy. Součtové datové typy. FLP - Uživatelem definované typy

Funkcionální programování Haskell

Funkcionální programování Haskell

Funkcionální programování Haskell

Obsah přednášky. programovacího jazyka. Motivace. Princip denotační sémantiky Sémantické funkce Výrazy Příkazy Vstup a výstup Kontinuace Program

IB015 Neimperativní programování. Časová složitost, Typové třídy, Moduly. Jiří Barnat Libor Škarvada

Martin Milata, Pokud je alespoň jeden rozměr čokolády sudý (s výjimkou tabulky velikosti 1x2, která už je od

Funkcionální programování. Kristýna Kaslová

Paradigmata programování 1

IB015 Neimperativní programování. Redukční strategie, Seznamy program QuickCheck. Jiří Barnat Libor Škarvada

Generování vnitřní reprezentace programu

Paradigmata programování 1

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

NPRG030 Programování I, 2018/19 1 / :03:07

Functional and Logic Programming Functional languages

Konstruktory překladačů

PG 9.5 novinky ve vývoji aplikací

Informační systémy 2008/2009. Radim Farana. Obsah. Dotazy přes více tabulek

ALG 09. Radix sort (přihrádkové řazení) Counting sort. Přehled asymptotických rychlostí jednotlivých řazení. Ilustrační experiment řazení

Univerzita Palackého v Olomouci Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 3.4.

Programování v Haskellu KSI MFF CUNI CZ 2019

Základní datové struktury III: Stromy, haldy

Úvod do programovacích jazyků (Java)

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Programování v Pythonu

Dotazování nad stromem abstraktní syntaxe

Úvod do programovacích jazyků (Java)

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Druhy souborů. textové. binární. nestrukturované txt strukturované - ini, xml, csv. veřejné bmp, jpg, wav proprietární docx, cdr, psd

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

Java/QE Akademie - Osnova

SII - Informatika. 1. Atribut relace, jehož hodnota jednoznačně určuje prvek v jiné relaci, se nazývá:

IB015 Neimperativní programování. Organizace a motivace kurzu, programovací jazyk Haskell. Jiří Barnat

Motivace. Vstup a výstup. Minimální komunikace. Motivace. ÚDPJ - Vstup a výstup. Ing. Lumír Návrat katedra informatiky, A

DSA, První krok: máme dokázat, že pro left = right vrátí volání f(array, elem, left, right)

JAVA. Další jazyky kompilovatelné do Java byte-code

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 5. CVIČENÍ

Rekurzivní algoritmy

Programovací jazyk Pascal

Object Pascal je přísně typový procedurální jazyk, který umožňuje jak strukturované, tak objektově orientované programování.

PB161 Programování v jazyce C++ Přednáška 3

Semestrální práce z předmětu. Jan Bařtipán / A03043 bartipan@studentes.zcu.cz

Haskell Hero učební text

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Stromy, haldy, prioritní fronty

Kurz Databáze. Obsah. Dotazy. Zpracování dat. Doc. Ing. Radim Farana, CSc.

KTE / ZPE Informační technologie

Zápis programu v jazyce C#

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

PARADIGMATA PROGRAMOVÁNÍ 2 PŘÍSLIBY A LÍNÉ VYHODNOCOVÁNÍ

Paradigmata programování II Korutiny a nedeterminismus

Java a XML. 10/26/09 1/7 Java a XML

Abstraktní datové typy

Univerzita Palackého v Olomouci Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 12.2.

Knihovna XmlLib TXV první vydání prosinec 2010 změny vyhrazeny

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

PARADIGMATA PROGRAMOVÁNÍ 2A INTERPRET S VEDLEJŠÍMI EFEKTY A MAKRY

PB161 Programování v jazyce C++ Přednáška 9

Šablony, kontejnery a iterátory

SPJA, cvičení 1. ipython, python, skripty. základy syntaxe: základní datové typy, řetězce. podmínky: if-elif-else, vyhodnocení logických výrazů

Implementace LL(1) překladů

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Přednáška 3. Rekurze 1

Dynamické programování. Optimální binární vyhledávací strom

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

NPRG030 Programování I, 2016/17 1 / :58:13

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 23, 2016

Knihovna XmlLib TXV druhé vydání říjen 2012 změny vyhrazeny

Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague

Algoritmizace prostorových úloh

VÝRAZY výrazy = operandy prokládané operátory, vyhodnocované podle priority operátorů

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

PB161 Programování v jazyce C++ Přednáška 6

ŘÍDÍCÍ STRUKTURY - PODMÍNKY

PB přednáška (26. října 2015)

IB111 Programování a algoritmizace. Objektově orientované programování (OOP)

PARADIGMATA PROGRAMOVÁNÍ 2A MAKRA III

Reprezentace dat v informačních systémech. Jaroslav Šmarda

Stromy. Příklady. Rekurzivní datové struktury. Základní pojmy

Náznak ukázky syntaxe a sémantiky pro projekt. 1 Syntaktické prvky. Poslední aktualizace: 8.

PB161 Programování v jazyce C++ Přednáška 3

9. přednáška - třídy, objekty

Abstraktní datové typy: zásobník

Tabulka obsluhovaná kódem VBA

Základy jazyka C# Obsah přednášky. Architektura.NET Historie Vlastnosti jazyka C# Datové typy Příkazy Prostory jmen Třídy, rozhraní

5 Přehled operátorů, příkazy, přetypování

Jazyk VHDL zápis čísel, znaků a řetězců. Jazyk VHDL základní datové typy a operátory. Kurz A0B38FPGA Aplikace hradlových polí

Algoritmizace prostorových úloh

Dotazovací jazyk pro řazená data

NPRG030 Programování I, 2010/11

Úvod do programování - Java. Cvičení č.4

Přednáška 7. Celočíselná aritmetika. Návratový kód. Příkazy pro větvení výpočtu. Cykly. Předčasné ukončení cyklu.

Příklad : String txt1 = new String( Ahoj vsichni! ); //vytvoří instanci třídy String a přiřadí ji vnitřní hodnotu Ahoj vsichni!

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

awk programovatelný filtr

R zné algoritmy mají r znou složitost

Transkript:

-- literate haskell.lhs -- radky zacinaji > {- > lhsfunkce x = lhstelo (x * x) > where > lhstelo y = y div 2 -- z prelude foldr :: (a->b->b) -> b -> [a] -> b foldr f v [] = v foldr f v (x:xs) = f x (foldr f v xs) (.) :: (b->c) -> (a->b) -> (a->c) (f. g) x = f (g x) -- > test0 x = faze3 ( faze2 ( faze1 x ) ) -- > test1 x = (faze3. faze2. faze1) x -- > test2 = faze3. faze2. faze1 -- stejne typy infixr 0 $ ($) :: (a->b) -> a -> b f $ x = f x -- > test3 x = faze3 $ faze2 $ faze1 x infixr 0 $! ($!) :: (a->b) -> a -> b f $! x =... interni, pro striktni vyhodnocovani -- vyhodnoti top konstruktor x -} 1

----------------------------------- -- 11.5.2009 stromy -- (1) data len v listoch data LTree a = LLeaf a LBranch (LTree a) (LTree a) -- (2) data interne, BVS data BTree a = BLeaf BBranch (BTree a) a (BTree a) -- BVS = BTree (TKey,TValue) -- dvojice :-( -- (3) data: ine v listoch, ine vnutri data DTree a b = DLeaf a DBranch (DTree a b) b (DTree a b) binvyraz :: DTree Int String binvyraz = DBranch (DLeaf 1) "+" (DBranch (DLeaf 2)"*"(DLeaf 3)) -- R-B trees... t1btree = BBranch (BBranch BLeaf 1 BLeaf) 2 (BBranch (BBranch BLeaf 3BLeaf) 4 (BLeaf) ) {- typovy konstruktor BTree, LTree druhu(::) * -> * typ.k. DTree druhu (kind) *->*->* -- datovy konstruktor BLeaf :: BTree a -- polymorfni dat.k. BBranch :: BTree a -> a -> BTree a -> BTree a dat.k. DLeaf :: a -> DTree a b -} 2

foldbt :: b->(b->a->b->b)->btree a-> b -- ala foldr pro seznamy (strukt. rek.) foldbt fleaf fbranch bt = f bt where f BLeaf = fleaf f (BBranch l x r) = fbranch (f l) x (f r) copybt t = foldbt BLeaf BBranch t -- "identita" sizebt t = foldbt 0 (\l x r->l+1+r) t depthbt t = foldbt 1 (\l x r->1+max l r) t listify t = foldbt [] (\l x r->l++(x:r)) t -- infixbt postfix t = foldbt [] (\l x r->l++r++[x]) t sumbt t = foldbt 0 (\l x r->l+x+r) t mapbt f t = foldbt BLeaf (\l x r->bbranch l (f x) r) t heapify t = foldbt BLeaf (\l x r->inheap l x r) t -- where inheap na dalsi strane prumer t = frominteger suma/frominteger size -- obecne: potrebuji postspracovani where (suma,size) = foldbt (0,0) (\(ls,lv) x (rs,rv)->(ls+x+rs,lv+1+rv)) t --bvs t = foldbt True (\l x r->l && r && locordered l x r) t -- where locordered l x r =... vaha :: BTree (Int,a) -> (Int,Int) -- (freq,key)-> (freq, vaha); vaha = sum(freq*depth) vaha t = foldbt (0,0) (\(fl,vl)(fx,_k)(fr,vr) ->(fl+fx+fr,vl+fl+fx+vr+fr) ) t --... a varianty fold: -- Obecne musim vracet i puvodni i spracovanou strukt. (tj. dvo 3

-- mkheap :: BTree a -> BTree a -- jen preusporadani, ne stavba mkheap BLeaf = BLeaf mkheap (BBranch l x r) = inheap (mkheap l) x (mkheap r) inheap BLeaf x BLeaf = BBranch BLeaf x BLeaf inheap l@(bbranch l1 xl l2) x BLeaf x <= xl = BBranch l x BLeaf True = BBranch (inheap l1 x l2) xl BLeaf inheap BLeaf x r@(bbranch r1 xr r2) x <= xr = BBranch BLeaf x r True = BBranch BLeaf xr (inheap r1 x r2) inheap l@(bbranch l1 xl l2) x r@(bbranch r1 xr r2) x <= xl && x <= xr = BBranch l x r xl<= xr = BBranch (inheap l1 x l2) xl r True = BBranch l xr (inheap r1 x r2) -- aktivni konstruktory: buduji pozmenenou strukturu t1heap = bbranch (bbranch bleaf 1 bleaf) 2 (bbranch (bbranch bleaf 3 bleaf) 4 (bleaf) ) where bleaf = BLeaf bbranch = inheap 4

---------------- -- stromy n-arne (Rose Tree) data RTree a = RT a [RTree a] -- aplikace: XML... data XML a = Elm a [XML a] Txt String -- a/string -- jen tag -- a/(string,[(string,string)]) -- show bez chyb, praca so zoznamami elementov {- -- aplikace: univ.vyrazy, synt. stromy... data Expr a = Var String Fn String [Expr a]... Con a If (Expr Bool) (Expr a) (Expr a) Inc (Expr Int) -- vyrazy v FP, nejen PP -- fantomove typy -} 5

-- huffmanovo kodovani: optimalni, hladovy alg. -- vzdaleny ;-) cil {- test_hde s = let t = mkhtree $ freq s in s == (dec t $ enc (hstrom2tab t) s) -} data HStrom a = HL a HV (HStrom a) (HStrom a) hstrom2tab :: HStrom (Char {-,Int-}) -> [(Char,String)] hstrom2tab (HL(c)) = [(c,"")] hstrom2tab (HV l r) = map (\(c,kod)->(c, 0 :kod)) (hstrom2tab l) ++ map (\(c,kod)->(c, 1 :kod)) (hstrom2tab r) -- volani> hs2t "" strom -- akumulator hs2t kod (HL(c,"")) = [(c,kod)] hs2t kod (HV l r) = hs2t (kod++"0") l ++ hs2t (kod++"1") r enc :: (Eq a,show a) => [(a,[b])] -> [a] -> [b] enc tab [] = [] enc tab (x:xs) = enc1 tab x ++ enc tab xs where enc1 [] x = error("enc: missing code for:"++show x) enc1 ((x1,kod):tab) x = if x==x1 then kod else enc1 tab x 6

enc2 tab xs = concat(map(\x -> snd(head(filter (f x) tab))) xs) where f x = \(x1,_kod) -> x==x1 -- x: lambda-lifting -- f x = (x==).fst -- varianta -- = concat $ map (\x -> snd $ head $ filter f tab) xs -- concat [] = [] -- v Prelude -- concat (x:xs) = x ++ concat xs -- anebo: concat xss = foldr (++) [] xss 7

dec :: HStrom a -> [Char] -> [a] dec strom [] = [] dec strom inp = c : dec strom inp1 where (c, inp1) = dec1 strom inp dec1 :: HStrom a -> [Char] -> (a,[char]) dec1 (HL c) inp = (c,inp) dec1 (HV l r) ( 0 :inp) = dec1 l inp dec1 (HV l r) ( 1 :inp) = dec1 r inp dec1 (HV l r) ( x :inp) = error ("dec: bad code:"++show x) dec1 (HV l r) [] = error "dec: unexpected EOF" dec2 :: HStrom a -> [Char] -> [a] dec2 strom inp = case x of Nothing -> [] -- interni chyba: nic se nedekoduje Just (c,inp1) -> c : dec strom inp1 where x = dec1 strom inp dec1 :: HStrom a -> [Char] -> Maybe (a,[char]) dec1 (HL c) inp = Just (c,inp) dec1 (HV l r) ( 0 :inp) = dec1 l inp dec1 (HV l r) ( 1 :inp) = dec1 r inp dec1 (HV l r) ( x :inp) = Nothing dec1 (HV l r) [] = Nothing -- pozn: odebirana cast je dana kontextem {- data Maybe a = Nothing Just a deriving (Eq, Show) -} 8

mkhtree :: [(Char,Int)] -> HStrom Char mkhtree xs = faze5 where cmp (c1,f1) (c2,f2) = f1<=f2 -- cmp = \(c1,f1) (c2,f2) -> f1<=f2 faze1 = sort cmp xs faze2 = map (\(c,f) -> (HL c, f)) faze1 faze3 = iterate spoj faze2 faze4 = dropwhile (\x -> length x > 1) faze3 faze5 = fst $ head $ head faze4 spoj [x] = [x] spoj ((c1,f1):(c2,f2):xs) = insert cmp (HV c1 c2,f1+f2) xs sort cc xs = foldr (insert cc) [] xs insert cc x [] = [x] insert cc x vs@(y:ys) x cc y = (x:vs) True = y:insert cc x ys 9

freq :: String -> [(Char,Int)] -- histogram freq xs = foldr ordbagunion [] $ map (\x->[(x,1)]) xs -- O(n^2) :-( ordbagunion [] ys = ys ordbagunion xs [] = xs ordbagunion xx@((x,fx):xs) yy@((y,fy):ys) x < y = (x,fx) :ordbagunion xs yy x == y = (x,fx+fy):ordbagunion xs ys -- memory leak x > y = (y,fy) :ordbagunion xx ys folddvoj f e [] = [] folddvoj f e xs = (head.head.dropwhile((1<).length).iterate(spojdvoj f))xs where spojdvoj f (x1:x2:xs) = f x1 x2 : spojdvoj f xs spojdvoj f xs = xs freq2 xs = folddvoj ordbagunion [] $ map (\x->[(x,1)]) xs testfreq k c = [s s<-varopak1 k [ a..c], let s1=s, freq2 s /= freq s ] -- testfreq 7 f : 1 23, length 279936 testov {- prelude iterate :: (a->a) -> a -> [a] iterate f x = x : iterate f (f x) dropwhile :: (a->bool) -> [a] -> [a] dropwhile _ [] = [] dropwhile p (x:xs) p x = dropwhile p xs otherwise = x : xs -- DC: ukoncenie podla vztahu dvoch prvkov -} 10

varopak :: [a] -> [b] -> [[(a,b)]] varopak [] _ = [[]] -- vhodne "dodefinovano" varopak (x:xs) r = [(x,y):vs y<-r, vs <- varopak xs r] varopak1 :: Int -> [b] -> [[b]] varopak1 k r = map -- pro všechny variace (map -- pro všechny prvky ve var. snd) -- zahazuju dom., vracím hodnotu (varopak -- volání puv. fce dostane: [1..k] -- domain jako seznam r) -- range bez zmen komb :: Int -> [a] -> [[a]] komb 0 _ = [[]] -- vhodne "dodef." komb (n+1) [] = [] komb (n+1) (x:xs) = [x:ko ko <- komb n xs] ++ komb (n+1) xs kombopak :: Int -> [a] -> [[a]] kombopak 0 _ = [[]] -- vhodne "dodef." kombopak (n+1) [] = [] kombopak (n+1) (xs) = [head xs:ko ko <- kombopak n xs] ++ kombopak (n+1) (tail xs) 11

-- testy: QuickCheck 2000, SmallCheck 2008,... test_hde s = let t=mkhtree $ freq s in s == (dec t $ enc (hstrom2tab t) s) prop_hde k c = [s s<-kombopak k [ a..c], not $ test_hde s] -- varopak1 -- > prop_hde 3 b -- >> ["aaa","bbb"] Obsahlejsi popis napr. Huffmanova kodovani v textu "Haskell v pr -- s kombopak: 15 g : 35, 54264 testov -- s varopak1: 7 f : okolo 2, 279936 testov {- -- Zde ukonceno na Prednasce 12.05.2009, -- nektere drobnosti preskocene --------------------------------------------- -} 12

----------- stablesort cmp xs = map fst $ -- odstraneni poradi (A) sort1 cmp2 $ -- trideni se zmenou porovnavaci fce (B) zip xs [1..] --pridani poradi (C) where cmp2 (x,i) (y,j) = x cmp y && not (y cmp x) x cmp y && y cmp x && i <= j sort1 cmp [] = [] sort1 cmp (p:ys) = sort1 cmp ([y y<-ys,y cmp p]++(p:[y y<-ys,not$y cmp p])) {- -- add F# (.NET), Scala (nad JVM) lift: na Maybe, Either na zoznamy (vektory), matice na funkcie - casova zavislost DSEL - Domain Specific (Embedded) Language fantomove typy Calling hell from heaven and heaven from hell, 1999 kontext Blub: hypoteticky prog. jazyk, Paul Graham -} 13

-------------- -- (tvorba indexu: reverzny zoznam) type Word = String splitwords :: String -> [Word] splitwords st = split (dropspace st) split :: String -> [Word] - dostává ř. bez úvodních mezer split [] = [] split st = (getword st):split(dropspace(dropword st)) dropspace st = dropwhile (\x->elem x whitespace) st dropword st = dropwhile (\x->not(elem x whitespace)) st dropwhile :: (t -> Bool) -> [t] -> [t] - obecná výkonná procedur dropwhile p [] = [] -- zahodí poč. prvky, které nesplňují podm. dropwhile p (a:x) -- v prelude p a = dropwhile p x otherwise = (a:x) getword st = takewhile (\x-> not(elem x whitespace)) st -- DC: takewhile p x = -- v prelude whitespace = [, \t, \n] 14

Aritmetika s testováním chyb (pomocí Maybe) lift2m :: (a->b->c)->maybe a -> Maybe b -> Maybe c lift2m op Nothing _ = Nothing chyba v 1. arg. lift2m op _ Nothing = Nothing chyba v 2. arg. lift2m op (Just x) (Just y) = Just (x op y) bez chyb minusm :: Maybe Float -> Maybe Float -> Maybe Float minusm x y = lift2m (-) x y -- Vyvolání chyby delenom x y = if y==just 0 then Nothing --test a vyvolání chyby else lift2m (/) x y? delenom(just 3)(minusM(Just 2)(Just 2)) -- 3/(2-2)? delenom(just 3)(lift2M(-)(Just 2)(Just 2)) -- dtto Nothing data AV a = AV a :-: AV a AV a :/: AV a Con a eval :: AV Integer -> Maybe Integer eval (av1 :/: av2) = delenom (eval av1) (eval av2) eval (av1 :-: av2) = lift2m (-) (eval av1) (eval av2) eval (Con x) = Just x -- cena za Maybe: zabalení výsledku -- Odchycení chyby:? catch (eval (Con 3 :/: (Con 2 :-: Con 2)) ) 1 catch Nothing oprdata = opravnafce oprdata catch (Just x) _ = x 15

map pro jiné d.s. pro binární stromy rozbor podle konstruktoru maptree :: (a->b) -> Tree a -> Tree b maptree f (Leaf a) = Leaf (f a) maptree f (Branch l r) = Branch (maptree f l) (maptree f r) n-ární stromy data NTree a = Tr a [NTree a] mapnt :: (a->b) -> NTree a -> NTree b mapnt f (Tr x trees) = Tr (f x) (map (mapnt f) trees) typ Maybe, Union - nerekurzivní mapm :: (a->b) -> Maybe a -> Maybe b mapm f Nothing = Nothing mapm f (Just x)= Just (f x) mapu :: (a->c)->(b->d) -> Union a b -> Union c d mapu f g (Left x) = Left (f x) mapu f g (Right y) = Right(g y) 16

Stavové programování (Návrhový vzor iterátor) N.vzory ve FP lze (často) napsat jako kod s funkc. parametry vs. (často) pseudokód v OOP iterator::s->(s->s)->(s->bool)->s -- vrací celý (interní) stav, zde není výstupní projekce iterator init next done = head( dropwhile (not.done) --mezivýsl. se průběžně ( iterate next init ) ) -- zahazují DC: fixpoint :: (s->s)->s->s :vrací v=f^n(x) pro min. n:v=f(v) 17

Počítání s programy Typicky: dokazování vlastností programů (Částečná) správnost vzhledem k specifikaci Transformace programů pro optimalizaci př.: asociativita (++) append [] ++ ys = ys (x:xs) ++ ys = x: (xs++ys) Tvrzení: x++(y++z) = (x++y)++z pro konečné x, y, z. x=[] : LS = []++(y++z) = y++z PS = ([]++y)++z = y++z x=a:v : LS = (a:v)++(y++z) = / def. ++ a:(v++(y++z)) = / ind. předp. ++ a:((v++y)++z) PS = ((a:v)++y)++z = / def. ++ ((a:(v++y)) ++ z) = / def. ++ a:((v++y)++z) QED? 18