Tisztán funkcionális adatszerkezetek

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

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

Tulajdonságalapú tesztelés

Programozás burritokkal

Funkcionális Nyelvek 2 (MSc)

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

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

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

2018, Funkcionális programozás

2016, Funkcionális programozás

Funkcionális programozás

2016, Funkcionális programozás

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

S2-01 Funkcionális nyelvek alapfogalmai

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

2018, Funkcionális programozás

FUNKCIONÁLIS PROGRAMOZÁS GYAKORLAT JEGYZET

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

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.

HASKELL. Tartalom előadás

Tartalom előadás

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

Oktatási segédlet 2014

FUNKCIONÁLIS PROGRAMOZÁS

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

SQL*Plus. Felhasználók: SYS: rendszergazda SCOTT: demonstrációs adatbázis, táblái: EMP (dolgozó), DEPT (osztály) "közönséges" felhasználók

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

Adattípusok. Max. 2GByte

Adattípusok. Max. 2GByte

Collections. Összetett adatstruktúrák

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


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

Generikus keresőfák Erlangban

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

Táblakezelés: Open SQL Internal table. Tarcsi Ádám: Az SAP programozása 1.

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

Fejlett programozási nyelvek C++ Iterátorok

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

C++ Standard Template Library (STL)

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

Bevezetés a programozásba 2

Sztringkezelő függvények. A string típusú változók kezelése, használata és szerepük a feldolgozás során

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

van neve lehetnek bemeneti paraméterei (argumentumai) lehet visszatérési értéke a függvényt úgy használjuk, hogy meghívjuk

2018, Funkcionális programozás

Programozási technológia

Az arrow struktúra. Patai Gergely április 1.

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

Láncolt listák Témakörök. Lista alapfogalmak

Adatbázisok* tulajdonságai

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

Kifejezések. Kozsik Tamás. December 11, 2016

Kifejezések. Kozsik Tamás. December 11, 2016

Proxer 7 Manager szoftver felhasználói leírás

Adatbázis-kezelés ODBC driverrel

II. év. Adatbázisok és számítógépek programozása

A lista adatszerkezet A lista elemek egymásutániságát jelenti. Fajtái: statikus, dinamikus lista.

Algoritmusok és adatszerkezetek gyakorlat 06 Adatszerkezetek

Tuplet Tool Hangjegycsoport eszköz

LUSTA KIÉRTÉKELÉS, LUSTA LISTA

Ugrólisták. RSL Insert Example. insert(22) with 3 flips. Runtime?

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

Fordított és szkript nyelvek összehasonlító elemzése. Sergyán Szabolcs

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

Széchenyi István Egyetem

2018, Funkcionális programozás

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

Komputeralgebra Rendszerek

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

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

SQL- Utasítások csoportosítása Definíció: DDL: - objektum létrehozás CREATE - objektum megszüntetés DROP - objektum módosítás ALTER

Funkcionális és logikai programozás. { Márton Gyöngyvér, 2012} { Sapientia, Erdélyi Magyar Tudományegyetem }

SQL haladó. Külső összekapcsolások, Csoportosítás/Összesítés, Beszúrás/Törlés/Módosítás, Táblák létrehozása/kulcs megszorítások

Programozás C++ -ban 2007/4

Adatszerkezetek és algoritmusok

Bevezetés a Programozásba II 12. előadás. Adatszerkezetek alkalmazása (Standard Template Library)

Adatbázis használat I. 5. gyakorlat

Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia

BEVEZETÉS Az objektum fogalma

Objektumok inicializálása

Önszervező bináris keresőfák

Pénzügyi algoritmusok

WEBFEJLESZTÉS 2. ADATBÁZIS-KEZELÉS, OSZTÁLYOK

BGF. 4. Mi tartozik az adatmodellek szerkezeti elemei

Egyszabadságfokú grejesztett csillapított lengõrendszer vizsgálata

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

Java. Perzisztencia. ANTAL Margit. Java Persistence API. Object Relational Mapping. Perzisztencia. Entity components. ANTAL Margit.

Adatszerkezetek és algoritmusok

Algoritmusok és adatszerkezetek gyakorlat 07

Adatbázis-kezelés, információs-rendszerek

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

Adatbáziskezelő-szerver. Relációs adatbázis-kezelők SQL. Házi feladat. Relációs adatszerkezet

Adatbázis Rendszerek II. 5. PLSQL Csomagok 16/1B IT MAN

HASZNÁLATI TANÁCSOK H.3

STL. Algoritmus. Iterátor. Tároló. Elsődleges komponensek: Tárolók Algoritmusok Bejárók

Programozási nyelvek Java

Komponensek együttműködése web-alkalmazás környezetben. Jónás Richárd Debreceni Egyetem T-Soft Mérnökiroda KFT

1. Gyakorlat: Telepítés: Windows Server 2008 R2 Enterprise, Core, Windows 7

Átírás:

Tisztán funkcionális adatszerkezetek

Bevezetés A hatékony adatszerkezetek általában... [..] language-independent only in the sense of Henry Ford: Programmers can use any language as they want, as long as it s imperative. Chris Okasaki, Purely Functional Data Structures, 1996 Az imperatív adatszerkezetek viszont: Gyakran döntő mértékben támaszkodnak az elemek felülírására ( destructive update ) Ezáltal nem tisztán funkcionálisak, mivel azok mindig (automatikusan) perzisztensek: az adatszerkezet régi állapotai is elérhetőek Hatékony (megvalósítható) perzisztencia: lusta kiértékelés, memoization, amortizáció. [2..38]

Hogyan és hol jelenik meg a perzisztencia? xs = fromlist [a, b, c, d, f, g, h] ys = insert e xs xs ys d d' b g g' a c f h f' e [3..38]

Egy kis ismétlés: listák data [α] = α :+: [α] [] (:) :: α [α] [α] x : xs = x :+: xs ( ++ ) :: [α] [α] [α] [] ++ ys = ys (x :+: xs) ++ ys = x : (xs ++ ys) [4..38]

Egy kis ismétlés: listák [5..38]

Egy kis ismétlés: listák [6..38]

Egy kis ismétlés: listák [7..38]

Listák: a költségek elemzése xs 1 = xs 0 ++ ys 1 -- költség: length xs 0 xs 2 = xs 1 ++ ys 2 -- költség: length (xs 0 ++ ys 1 ) xs 3 = xs 2 ++ ys 3 -- költség: length (xs 0 ++ ys 1 ++ ys 2 ) xs N = xs N 1 ++ ys N -- költség: length (xs 0 ++ ys 1 ++... ++ ys N 1 ) [8..38]

Továbbfejlesztés: differencialisták A differencialista egy olyan füuggvény, amely visszaadja a benne tárolt listát a paramétereként kapott lista után fűzve. -- http://hackage.haskell.org/package/dlist newtype DiffList α = DFL ([α] [α]) Konstans idejű hozzáfűzést tesz lehetővé a lista elejére és a végére. [9..38]

Differencialista: a költségek elemzése (áttekintés) xs 1 = (fromlist xs 0 ) append (fromlist ys 1 ) -- költség: 1 xs 2 = (fromlist xs 1 ) append (fromlist ys 2 ) -- költség: 1 xs 3 = (fromlist xs 2 ) append (fromlist ys 3 ) -- költség: 1 xs N = (fromlist xs N 1 ) append (fromlist ys N ) -- költség: 1 tolist xs N -- költség: length (xs 0 ++ys 1 ++... ++ys N ) [10..38]

Differencialista: implementáció (1) fromlist :: [α] DiffList α fromlist dl = DFL (λ xs. dl ++ xs) apply :: DiffList α [α] [α] apply (DFL f ) xs = f xs tolist :: DiffList α [α] tolist df = apply df [] empty :: DiffList α empty = DFL (λ xs. xs) singleton :: α DiffList α singleton x = DFL (λ xs. x : xs) [11..38]

Differencialista: implementáció (2) infixr cons cons :: α DiffList α DiffList α x cons (DFL f ) = DFL ((x :) f ) infixl snoc snoc :: DiffList α α DiffList α (DFL f ) snoc x = DFL (f (x :)) append :: DiffList α DiffList α DiffList α append (DFL f ) (DFL g) = DFL (f g) concat :: [DiffList α] DiffList α concat = Data.List.foldr append empty [12..38]

Differencialista: implementáció (3) replicate :: Int α DiffList α replicate n x = DFL $ λ xs. let f m m 0 = xs otherwise = x : f (m 1) in f n foldr :: (α β β) β DiffList α β foldr f b = Data.List.foldr f b tolist map :: (α β) DiffList α DiffList β map f = foldr (cons f ) empty [13..38]

Interlude: Zipper A zipper az adatszerkezet egy olyan ábrázolási módja, amely megkönnyíti annak bejárását és elemeinek módosítását. "gap buffer": ugyanazon pozícióhoz (kurzorhoz) tartozó beszúrások és törlések nyalábolása, optimalizációja az amortizált költsége kevés. Gyakran alkalmazzák nagyobb méretű adatszerkezetekben való mozgásra vagy fókuszálásra, például: Fókusz és ablakok elhelyezésének kezelése (xmonad) Szövegszerkesztők Tranzakciós szemantikával rendelkező állományrendszerek http://hackage.haskell.org/package/zfs Ez a megoldás tetszőleges rekurzívan definiált adatszerkezet (lista, fa stb.) esetén alkalmazható. [14..38]

Kétirányú listák: "List with Zipper" [15..38]

Kétirányú listák: "List with Zipper" [16..38]

Kétirányú listák: implementáció (1) newtype ZippList α = ZPL ([α], [α]) fromlist :: [α] ZippList α fromlist xs = ZPL ([], xs) tolist :: ZippList α [α] tolist (ZPL (xs, ys)) = reverse xs ++ ys get :: ZippList α [α] get (ZPL (_, ys)) = ys [17..38]

Kétirányú listák: implementáció (2) right :: ZippList α ZippList α right (ZPL (xs, (y : ys))) = ZPL (y : xs, ys) right zl = zl left :: ZippList α ZippList α left (ZPL ((x : xs), ys)) = ZPL (xs, x : ys) left zl = zl put :: Either α α ZippList α ZippList α put (Left e) (ZPL (xs, ys)) = ZPL (e : xs, ys) put (Right e) (ZPL (xs, ys)) = ZPL (xs, e : ys) putleft = put Left putright = put Right [18..38]

Kétirányú listák: implementáció (3) modify :: (α Maybe α) ZippList α ZippList α modify f (ZPL (xs, y : ys)) = ZPL $ case (f y) of Nothing (xs, ys) Just e (xs, e : ys) modify _ zl = zl update f = modify (Just f ) delete = modify (const Nothing) [19..38]

Kétirányú fák: "Tree with Zipper" [20..38]

Kétirányú fák: "Tree with Zipper" [21..38]

Kétirányú fák: "Tree with Zipper" [22..38]

Kétirányú fák: "Tree with Zipper" [23..38]

Kétirányú fák: implementáció (1) data Tree α = Branch (Tree α) (Tree α) Leaf α data TreeContext α = Top L (TreeContext α) (Tree α) R (Tree α) (TreeContext α) type Location α γ = (α, γ) type TreeLocation α = Location (Tree α) (TreeContext α) [24..38]

Kétirányú fák: implementáció (2) treeleft :: TreeLocation α TreeLocation α treeleft (Branch l r, c) = (l, L c r) treeright :: TreeLocation α TreeLocation α treeright (Branch l r, c) = (r, R l c) treetop :: Tree α TreeLocation α treetop t = (t, Top) treeup :: TreeLocation α TreeLocation α treeup (t, L c r) = (Branch t r, c) treeup (t, R l c) = (Branch l t, c) [25..38]

Kétirányú fák: implementáció (3) treeupmost :: TreeLocation α TreeLocation α treeupmost l@(t, Top) = l treeupmost l = treeupmost (treeup l) treechange :: TreeLocation α (Tree α Tree α) TreeLocation α treechange (t, c) f = (f t, c) Például: treeview :: TreeLocation α Tree α treeview (t, _) = t treechange ((treeright treeleft treetop) t) (const (Leaf 0)) [26..38]

Ráadás: Zipper monád newtype Zipper λ α = Zipper { unzipper :: State λ α } deriving (Functor, Applicative, Monad, MonadState λ) traverse :: Location α γ Zipper (Location α γ) α α traverse start tt = evalstate (unzipper tt) start move :: (Location α γ Location α γ) Zipper (Location α γ) α move f = do modify f gets fst change :: (α α) Zipper (Location α γ) α change f = do modify (λ (t, c). (f t, c)) gets fst [27..38]

Zipper monád: példa swaptree :: Zipper (TreeLocation α) (Tree α) swaptree = move swap where swap (t, R l c) = (l, L c t) swap (t, L c r) = (r, R t c) treemap :: (α Tree α) (Tree α Tree α Tree α) (Tree α Tree α) treemap leaf branch = λ t. (treetop t) traverse treemapm where treemapm = do t gets fst case t of Branch do move treeleft l mod treemapm swaptree r mod treemapm move treeup (change const) (branch l mod r mod ) Leaf x return (leaf x) [28..38]

FingerTree (intuíció) [29..38]

FingerTree (intuíció) [30..38]

FingerTree (intuíció) [31..38]

FingerTree (intuíció) [32..38]

FingerTree (intuíció) [33..38]

FingerTree (intuíció) [34..38]

FingerTree (intuíció) [35..38]

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)... [36..38]

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 [37..38]

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. [38..38]