Tisztán funkcionális adatszerkezetek (folytatás)

Hasonló dokumentumok
Tisztán funkcionális adatszerkezetek (folytatás)

Tisztán funkcionális adatszerkezetek

Tulajdonságalapú tesztelés

Programozás burritokkal

FUNKCIONÁLIS PROGRAMOZÁS ELŐADÁS JEGYZET

Funkcionális programozás

2018, Funkcionális programozás

DSL-eket kétféleképpen szoktak megvalósítani:

2016, Funkcionális programozás

Lineáris belsőpontos Newton-iteráció

S2-01 Funkcionális nyelvek alapfogalmai

FUNKCIONÁLIS PROGRAMOZÁS

Funkcionális Nyelvek 2 (MSc)

2018, Funkcionális programozás

Doktori értekezés. Diviánszky Péter 2012.

HASKELL. Tartalom előadás

Tartalom előadás

2016, Funkcionális programozás

2019, Funkcionális programozás. 5. el adás. MÁRTON Gyöngyvér

2019, Funkcionális programozás. 2. el adás. MÁRTON Gyöngyvér

FUNKCIONÁLIS PROGRAMOZÁS GYAKORLAT JEGYZET

Adatszerkezetek és algoritmusok

List<String> l1 = new ArrayList<String>(); List<Object> l2 = l1; // error

Fejlett programozási nyelvek C++ Iterátorok

Párhuzamos programozás Haskellben (folytatás)

A programozás alapjai előadás. Amiről szólesz: A tárgy címe: A programozás alapjai

2019, Funkcionális programozás. 4. el adás. MÁRTON Gyöngyvér

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

Felhasználó által definiált adattípus

Programozási technikák Pál László. Sapientia EMTE, Csíkszereda, 2009/2010

ABSZTRAKCIÓ FÜGGVÉNYEKKEL (ELJÁRÁSOKKAL)

Algoritmusok és adatszerkezetek II.

Programozási nyelvek II.: JAVA, 4. gyakorlat

Feladat. Ternáris fa. Típusspecikáció. Reprezentáció. Absztrakt implementáció. Érdi Gerg EAF II. 4/3.

Logikai és funkcionális programozás funkcionális programozás modul

C# gyorstalpaló. Készítette: Major Péter

Bevezetés a programozásba II. 5. Előadás: Másoló konstruktor, túlterhelés, operátorok

A lista eleme. mutató rész. adat rész. Listaelem létrehozása. Node Deklarálás. Létrehozás. Az elemet nekünk kell bef zni a listába

Adatbázisok* tulajdonságai

Generikus osztályok, gyűjtemények és algoritmusok

Bánsághi Anna 2014 Bánsághi Anna 1 of 33

Operációs Rendszerek II. labor. 2. alkalom

Komputeralgebra Rendszerek

Az F# nyelv erőforrásanalízise

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

C++ programozási nyelv Konstruktorok-destruktorok

Funkcioná lis prográmozá s Start

Bevezetés a programozásba 2

2018, Funkcionális programozás

C# Nyelvi Elemei. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Nyelvi Elemei / 18

Programozási technológia


2. Beadandó feladat dokumentáció

Tervminták II. (Híd, Bejáró, Gyártófüggvény) Halmaz és bejárása Osztály-sablonok

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

Programozási nyelvek Java

OOP #14 (referencia-elv)

Java II. I A Java programozási nyelv alapelemei

Széchenyi István Egyetem. Programozás III. Varjasi Norbert

Programozás II. 2. Dr. Iványi Péter

Informatika terméktervezőknek

Komputeralgebra rendszerek

Adatbázisok elmélete 10. előadás

Komputeralgebra rendszerek

Absztrakt adattípus - algebrai specifikáció - Lists (paraméteres) module imports end exports parameters variables sorts operations equations

A feladat lényege egy felhasználói típusnak a zsák típusnak a megvalósítása.

Dinamikus láncolt lista 4. GYAKORLAT

3. Osztályok II. Programozás II

Generikus Típusok, Kollekciók

C++ Standard Template Library (STL)

Java Programozás 9. Gy: Java alapok. Adatkezelő 5.rész

Programozási nyelvek II.: JAVA, 4. gyakorlat

Oktatási segédlet 2014

Objektumok inicializálása

Megoldások. ξ jelölje az első meghibásodásig eltelt időt. Akkor ξ N(6, 4; 2, 3) normális eloszlású P (ξ

Bevezetés, a C++ osztályok. Pere László

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Java és web programozás

Access adatbázis elérése OLE DB-n keresztül

Adatbázis-kezelés ODBC driverrel

Csempe átíró nyelvtanok

Feldspar: Nyelv digitális jelfeldolgozáshoz

OOP: Java 11.Gy: Enumok, beágyazott osztályok. 13/1 B ITv: MAN

Programok értelmezése

Virtuális függvények (late binding)

Java II. I A Java programozási nyelv alapelemei

117. AA Megoldó Alfréd AA 117.

8. Gyakorlat SQL. DDL (Data Definition Language) adatdefiníciós nyelv utasításai:

Programozás alapjai. 5. előadás

Programozás C és C++ -ban

Láncolt Listák. Adat1 Adat2 Adat3 ø. Adat1 Adat2 ø Adat3

Rekurzió. Dr. Iványi Péter

Dinamikus adatszerkezetek. 2D generikus tömb: C++ 2D generikus tömb: C++

Dinamikus adatszerkezetek. 2D generikus tömb: C++ 2D generikus tömb: C++ 2D tömb: Java versus C++ 2D tömb: Java.

SQL ALAPOK. Bevezetés A MYSQL szintaxisa Táblák, adatok kezelésének alapjai

Programozási nyelvek Java

Collections. Összetett adatstruktúrák

Buborékrendezés: Hanoi Tornyai: Asszimptótikus fv.ek: Láncolt ábrázolás: For ciklussal:

Átírás:

Tisztán funkcionális adatszerkezetek (folytatás)

FingerTree (intuíció) [2..26]

FingerTree (intuíció) [3..26]

FingerTree (intuíció) [4..26]

FingerTree (intuíció) [5..26]

FingerTree (intuíció) [6..26]

FingerTree (intuíció) [7..26]

FingerTree (intuíció) [8..26]

Implementáció: társított (indexelt) típusszinonimák {-# LANGUAGE TypeFamilies, KindSignatures #-} class Collects α where type Elem α :: empty :: α insert :: Elem α α α... instance Eq (Elem [ε]) Collects [ε] where type Elem [ε] = ε empty = [] insert e xs = (e : xs)... [9..26]

Implementáció: nézetminták {-# LANGUAGE ViewPatterns #-} type Typ =... data TypView = Unit Arrow Typ Typ view :: Typ TypView view =... size :: Typ Integer size t = case (view t) of Unit 1 Arrow t 1 t 2 size t 1 + size t 2 Nézetminták segítségével pedig: size (view Unit) = 1 size (view Arrow t 1 t 2 ) = size t 1 + size t 2 [10..26]

Implementáció: mohón kiértékelt adatkonstruktorok data T = T!Int!Int A konstruktor! segítségével megjelölt paramétereit (strictness annotation) normálformára kell hozni, mielőtt azt alkalmazzuk. Körültekintéssel kell alkalmazni, mivel ez automatikusan nem vezet a teljesítmény növekedéséhez. Sőt, ronthatja a teljesítményt: ha az adott mezőt már egyszer kiértékeltük, akkor lényegében még egyszer kiértékeltetjük (feleslegesen). A helyzet tisztázásában a fordító nem mindig tud a segítségünkre lenni. [11..26]

Implementáció: egymásba ágyazott típusok -- alternáló lista data AList α β = Nil Cons α (AList β α) alist :: AList Int Char alist = Cons 1 (Cons A (Cons 2 (Cons B Nil))) -- ciklikus lista data Void data CList α β = Var β Nil RCons α (CList (Maybe β)) 1 2 clist 1, clist 2 :: CList Int Void 1 2 3 clist 1 = RCons 1 (RCons 2 (Var Nothing)) clist 2 = RCons 1 (RCons 2 (RCons 3 (Var (Just Nothing)))) A rekurzív részben az adattípust nem a deklaráció szerint alkalmazzuk: nested, non-regular, non-uniform, heterogenous data type Adattípusokon belüli invariánsok (típusozott) megtartására alkalmazható. [12..26]

FingerTree: definíció (1) class (Monoid (Measure α)) Measured α where type Measure α measure :: α Measure α data FingerTree α = Empty Single α Deep!(Measure α)!(digit α) (FingerTree (Node α))!(digit α) deep :: Measured α Digit α FingerTree (Node α) Digit α FingerTree α deep pr m sf = Deep (measure pr measure m measure sf ) pr m sf data Node α = Node2 (Measure α) α α Node3 (Measure α) α α α node2 :: Measured α α α Node α node2 x y = Node2 (measure x measure y) x y node3 :: Measured α α α α Node α node3 x y z = Node3 (measure x measure y measure z) x y z [13..26]

FingerTree: definíció (2) newtype Digit α = D { und :: [α] } prependdigit :: α Digit α Digit α prependdigit x (D xs) = D (x : xs) appenddigit :: Digit α α Digit α appenddigit (D xs) x = D (xs ++ [x]) breakdigit :: Digit α (α, Digit α) breakdigit (D (x : xs)) = (x, D xs) kaerbdigit :: Digit α (α, Digit α) kaerbdigit (D xs) = (last xs, D (init xs)) [14..26]

FingerTree: definíció (3) instance Measured α Measured (Node α) where type Measure (Node α) = Measure α measure (Node2 m ) = m measure (Node3 m _) = m instance Measured α Measured (Digit α) where type Measure (Digit α) = Measure α measure (D xs) = foldr ( ) mempty (map measure xs) instance Measured α Measured (FingerTree α) where type Measure (FingerTree α) = Measure α measure Empty = mempty measure (Single x) = measure x measure (Deep m _) = m [15..26]

FingerTree: létrehozás -- O(1) empty :: Measured α FingerTree α empty = Empty singleton :: Measured α α FingerTree α singleton = Single infixr 5 ( ) :: Measured α α FingerTree α FingerTree α x Empty = Single x x (Single y) = deep (D [x]) Empty (D [y]) x (Deep _ (D [y, z, u, w]) m sf ) = deep (D [x, y]) (node3 z u w m) sf x (Deep _ pr m sf ) = deep (prependdigit x pr) m sf -- O(n) ( ) :: Measured α [α] FingerTree α FingerTree α xs ys = foldr ( ) ys xs fromlist :: Measured α [α] FingerTree α fromlist xs = xs Empty digittotree :: Measured α Digit α FingerTree α digittotree (D xs) = fromlist xs Ugyanígy megadható a (végére illesztés) művelete is. [16..26]

FingerTree: elérés infixr 5 data ViewL α = EmptyL α (FingerTree α) -- O(1) viewl :: Measured α FingerTree α ViewL α viewl Empty = EmptyL viewl (Single x) = x Empty viewl (Deep _ pr m sf ) = p (deepl lpr m sf ) where (p, lpr) = breakdigit pr deepl :: Measured α Digit α FingerTree (Node α) Digit α FingerTree α deepl (D []) (viewl EmptyL) sf = digittotree sf deepl (D []) (viewl x m) sf = deep (nodetodigit x) m sf deepl pr m sf = deep pr m sf nodetodigit :: Measured α Node α Digit α nodetodigit (Node2 _ x y) = D [x, y] nodetodigit (Node3 _ x y z) = D [x, y, z] Ugyanígy megadható a viewr (végéről, jobbról balra bejárás) művelete is. [17..26]

FingerTree: elérés (alkalmazás) isempty :: Measured α FingerTree α Bool isempty (viewl EmptyL) = True isempty _ = False headl :: Measured α FingerTree α α headl (viewl x _) = x taill :: Measured α FingerTree α FingerTree α taill (viewl _ x) = x Hasonlóan létezik headr és tailr is. [18..26]

FingerTree: összekapcsolás infixr 5 -- O(log(min(n, m))) ( ) :: Measured α FingerTree α FingerTree α FingerTree α xs ys = f xs [] ys where f :: Measured α FingerTree α [α] FingerTree α FingerTree α f Empty ts xs = ts xs f xs ts Empty = xs ts f (Single x) ts xs = x (ts xs) f xs ts (Single x) = (xs ts) x f (Deep _ pr 1 m 1 sf 1 ) ts (Deep _ pr 2 m 2 sf 2 ) = deep pr 1 (f m 1 (nodes (und sf 1 ++ ts ++ und pr 2 )) m 2 ) sf 2 nodes :: Measured α [α] [Node α] nodes [x, y] = [node2 x y] nodes [x, y, z] = [node3 x y z] nodes [x, y, z, u] = [node2 x y, node2 z u] nodes (x : y : z : xs) = node3 x y z : nodes xs [19..26]

FingerTree: felbontás (1) data Split φ α = Split (φ α) α (φ α) i: kezdőérték, P( ): monoton predikátum, csak és P(i) P(i d ) = let Split l x r = splitdigit p i d in tolist l ++ [x] ++ tolist r = tolist d P(i l ) P(i l x ) splitdigit :: Measured α (Measure α Bool) Measure α Digit α Split Digit α splitdigit p i (breakdigit (x, D [])) = Split (D []) x (D []) splitdigit p i (breakdigit (x, xs)) p j = Split (D []) x xs otherwise = let Split l y r = splitdigit p j xs in Split (prependdigit x l) y r where j = i measure x x i-1 x i x 1 x 2 x i+1 x n-1 vn-1... P... P x n i v 1 v 2 v i-1 v i [20..26] vn

FingerTree: felbontás (2) P(i) P(i t ) = let Split l x r = splittree p i t in tolist l ++ [x] ++ tolist r = tolist t P(i l ) P(i l x ) -- O(log(min(n l, n r ))) splittree :: Measured α (Measure α Bool) Measure α FingerTree α Split FingerTree α splittree p i (Single x) = Split Empty x Empty splittree p i (Deep _ pr m sf ) p vpr = let Split l x r = splitdigit p i pr in Split (digittotree l) x (deepl r m sf ) p vm = let Split ml xs mr = splittree p vpr m Split l x r = splitdigit p (vpr measure ml) (nodetodigit xs) in Split (deepr pr ml l) x (deepl r mr sf ) otherwise = let Split l x r = splitdigit p vm sf in Split (deepr pr m l) x (digittotree r) where (vpr, vm) = (i measure pr, vpr measure m) [21..26]

FingerTree: felbontás (3) t Empty = let Split l x r = splittree p i t in tolist l ++ [x] ++ tolist r = tolist t (l = Empty P(i l )) (r = Empty P(i l x )) split :: Measured α (Measure α Bool) FingerTree α (FingerTree α, FingerTree α) split p Empty = (Empty, Empty) split p t p (measure t) = (l, x r) otherwise = (t, Empty) where Split l x r = splittree p mempty t [22..26]

FingerTree: véletlen elérésű sorozatok (alkalmazás) newtype Elem ν α = Elem { getelem :: α } -- ν : fantomtípus newtype Size = Size { getsize :: Int } deriving (Eq, Ord) newtype Seq α = Seq (FingerTree (Elem Size α)) instance Monoid Size where mempty = Size 0 mappend (Size m) (Size n) = Size (m + n) instance Measured (Elem Size α) where type Measure (Elem Size a) = Size measure (Elem _) = Size 1 fromlist :: [α] Seq α fromlist xs = Seq (FT.fromList (map Elem xs)) tolist :: Seq α [α] tolist (Seq t) = map getelem (FT.toList t) [23..26]

FingerTree: véletlen elérésű sorozatok (alkalmazás) length :: Seq α Int length (Seq xs) = getsize (FT.measure xs) splitat :: Int Seq α (Seq α, Seq α) splitat i (Seq xs) = (Seq l, Seq r) where (l, r) = FT.split (Size i <) xs (!) :: Seq α Int α (Seq xs)! i = getelem x where Split _ x _ = FT.splitTree (Size i <) (Size 0) xs [24..26]

FingerTree: prioritásos sor (alkalmazás) newtype PElem π α = PE (π, α) data Prio α = Prio α NoPrio deriving (Eq, Ord) instance Ord α Monoid (Prio α) where mempty = NoPrio mappend (Prio x) (Prio y) = Prio (min x y) mappend (Prio x) _ = Prio x mappend _ (Prio y) = Prio y mappend = NoPrio instance Monoid (Prio π) Measured (PElem (Prio π) α) where type Measure (PElem (Prio π) α) = Prio π measure (PE (i, _)) = i newtype PQueue π α = PQ (FingerTree (PElem (Prio π) α)) empty :: Ord π PQueue π α empty = PQ FT.empty null :: Ord π PQueue π α Bool null (PQ t) = FT.isEmpty t [25..26]

FingerTree: prioritásos sor (alkalmazás) singleton :: Ord π π α PQueue π α singleton k v = PQ (FT.singleton (PE (Prio k, v))) extractmin :: Ord π PQueue π α Maybe (α, PQueue π α) extractmin (PQ t) FT.isEmpty t = Nothing otherwise = Just (x, PQ (l r)) where Split l (PE (_, x)) r = FT.splitTree (FT.measure t ) mempty t union :: Ord π PQueue π α PQueue π α PQueue π α union (PQ p) (PQ q) = PQ (p q) insert :: Ord π π α PQueue π α PQueue π α insert k v q = union (singleton k v) q add :: Ord π π α PQueue π α PQueue π α add k v q = union q (singleton k v) fromlist :: Ord π [(π, α)] PQueue π α fromlist = foldr (λ (x, y). insert x y) empty [26..26]