S2-01 Funkcionális nyelvek alapfogalmai

Hasonló dokumentumok
FUNKCIONÁLIS PROGRAMOZÁS ELŐADÁS JEGYZET

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

Funkcionális Nyelvek 2 (MSc)

FUNKCIONÁLIS PROGRAMOZÁS

Programozás burritokkal

Tulajdonságalapú tesztelés

2016, Funkcionális programozás

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

Funkcionális programozás

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

2018, Funkcionális programozás

Alapok. tisztán funkcionális nyelv, minden függvény (a konstansok is) nincsenek hagyományos változók, az első értékadás után nem módosíthatók

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

Tisztán funkcionális adatszerkezetek

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

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

Java II. I A Java programozási nyelv alapelemei

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

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

2018, Funkcionális programozás

FUNKCIONÁLIS PROGRAMOZÁS GYAKORLAT JEGYZET

A C# programozási nyelv alapjai

Java II. I A Java programozási nyelv alapelemei

2016, Funkcionális programozás

Programozási nyelvek (ADA)

Rekurzió. Dr. Iványi Péter

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

2018, Funkcionális programozás

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

S0-02 Típusmodellek (Programozás elmélet)

Programok értelmezése

Tartalomjegyzék. I. Tillárom 3

Oktatási segédlet 2014

Occam 1. Készítette: Szabó Éva

Programozás BMEKOKAA146. Dr. Bécsi Tamás 2. előadás

2018, Funkcionális programozás

OOP #14 (referencia-elv)

2018, Funkcionális programozás

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

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

Feldspar: Nyelv digitális jelfeldolgozáshoz

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

Programozási nyelvek a közoktatásban alapfogalmak II. előadás

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Cekla. Készítette Doxygen Tue Sep :13:44

5. SOR. Üres: S Sorba: S E S Sorból: S S E Első: S E

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

Programozási nyelvek a közoktatásban alapfogalmak I. előadás

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

Informatika terméktervezőknek

Segédanyagok. Formális nyelvek a gyakorlatban. Szintaktikai helyesség. Fordítóprogramok. Formális nyelvek, 1. gyakorlat

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

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

Formális szemantika. Kifejezések szemantikája. Horpácsi Dániel ELTE Informatikai Kar

A C programozási nyelv I. Bevezetés

Programozási nyelvek Java

Járműfedélzeti rendszerek II. 1. előadás Dr. Bécsi Tamás

Adatszerkezetek és algoritmusok

Java programozási nyelv

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

Relációs algebra 1.rész alapok

Járműfedélzeti rendszerek II. 2. előadás Dr. Bécsi Tamás

KOMPUTER-ALGEBRA RENDSZEREK VERIFIKÁCIÓJA

Funkcionális nyelvek (egyetemi jegyzet) Páli Gábor János

Imperatív programozás

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

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

Számítástechnika I. BMEKOKAA152 BMEKOKAA119 Infokommunikáció I. BMEKOKAA606. Dr. Bécsi Tamás 2. előadás

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

A C programozási nyelv I. Bevezetés

A szemantikus elemzés elmélete. Szemantikus elemzés (attribútum fordítási grammatikák) A szemantikus elemzés elmélete. A szemantikus elemzés elmélete

Programozási nyelvek (ADA)

és az instanceof operátor

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Programozási nyelvek Java

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

Bevezetés a C++ programozási nyelvbe

Szoftvertechnológia alapjai Java előadások

A félév során előkerülő témakörök

A C programozási nyelv III. Pointerek és tömbök.

Algoritmusok és adatszerkezetek gyakorlat 03 Oszd meg és uralkodj. Nagy

Vezérlési szerkezetek

Már megismert fogalmak áttekintése

Objektumok inicializálása

Apple Swift kurzus 3. gyakorlat

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

BASH script programozás II. Vezérlési szerkezetek

sallang avagy Fordítótervezés dióhéjban Sallai Gyula

A C programozási nyelv III. Pointerek és tömbök.

A TANTÁRGY ADATLAPJA

Programozási nyelvek 6. előadás

Az UPPAAL egyes modellezési lehetőségeinek összefoglalása. Majzik István BME Méréstechnika és Információs Rendszerek Tanszék

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

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

Kiterjesztések sek szemantikája

A programozás alapjai 1 Rekurzió

Python tanfolyam Python bevezető I. rész

Programozás C és C++ -ban

Felvételi vizsga mintatételsor Informatika írásbeli vizsga

Átírás:

S2-01 Funkcionális nyelvek alapfogalmai Tartalom 1. Funkcionális nyelvek alapfogalmai Modell Kiértékelés Curry-zés Magasabbrendű függvények Listák Tisztaság 2. Típusok Algebrai adattípusok Típusosztályok Típuskonstruktorok Kindok 3. Monadikus programozás 4. További források 1.Funkcionális nyelvek alapfogalmai 1.1 Modell Funkcionális programozási paradigma, nyelvek Nem az algoritmust írjuk le = függvényekkel specifikáljuk a feladatot Deklaratív nyelvek családjába tartozik Imperatív nyelvek: HOGYAN csinálja meg a feladatot a program, utasítások írása, sokszor a memóriát is mi kezeljük Deklaratív nyelvek: MIT csináljon a program, magát a feladatot adjuk meg Minden program alapegysége a függvény Maga a program, programmodul az egy függvényhalmaz Program végrehajtása kezdeti függvénykifejezés (main) kiértékelése Matematikai számítási modellje a lambda-kalkulus (Érdekesség: szokták lambda-kalkulust a funkcionális nyelvek assembly-jének is hívni) Nincsenek változók, nincsen állapot, minden immutable, minden másolódik Iteráció helyett paraméterek mintaillesztése (pattern matching) és rekurzió Mintaillesztés + rekurzió: mint a teljes indukció matematikában Első minta: alapeset Rekurzív minta: indukciós lépés Funkcionális programozás előnyei 1. Közelebb áll a feladat és annak leírása 1

2. Szemlélete közelebb áll a formális, matematikai leíráshoz, precízebb 3. Helyességet könnyű kifejezni Hoare-hármasokat (elő-utó feltétel) könnyű funkcionális nyelvekkel leírni 4. Feladatosztályok absztrakcióinak kifejezése Van egy nagyon általános feladatsémám (nem algoritmus!) Ezt egy függvénnyel felparaméterezve (magasabbrendű függvények) eljutok a konkrétabb feladathoz 5. Kevesebb sor, tömörebb program, kevesebb hiba, könnyebb karbantarthatóság 6. Könnyű funkcionális programokat párhuzamosítani Például (2 + 3) + (7 + 1) Egyik CPU: (2 + 3) Másik CPU: (7 + 1) Minden asszociatív műveletre igaz: ha zárójelezünk, akkor több CPU tudja feldolgozni a zárójelezett részeket Végrehajtási modell Végrehajtási modell egy konfluens redukciós (átíró) rendszer Mitől konfluens: Az egyes részkifejezések átírásának sorrendje a végeredményre nincs hatással A sorrend legfeljebb azt befolyásolja = hogy az átírási lépéssorozattal eljutunk-e a végeredményig Tehát a végrehajtás redukciós, átírási lépések, redukáló kifejezések (redexek) sorozata 1.2 Kiértékelés Kiértékelőrendszer feladata Kiértékeli a specifikációt majd megadja a függvényértéket Függvénydefiníció részei 1. Függvény azonosító 2. Formális paraméterek 3. Függvény törzse Kiértékelés menete Átírási lépések (redukciók) sorozatával Átírási lépésben függvény alkalmazásában: függvény helyettesítése = függvény törzsével Addig írunk át, amíg el nem érjük a normálformát = azaz tovább már nem lehet átírni Kiértékelési stratégiák nem mások, mint redex-ek kiválasztási sorrendje. Ezek lehetnek: Mohó 2

Lusta Párhuzamos Lusta (Lazy) kiértékelés Nem fontos a függvénykiértékelések sorrendje Először a FÜGGVÉNYT értékeli ki Haskell-ban és Clean-ben: alapértelmezett kiértékelési mód squareinc 7 = square (inc 7) = (inc 7) * (inc 7) = 8 * (inc 7) = 8 * 8 = 64 Mohó (strict) kiértékelés Fontos a függvénykiértékelések sorrendje Először az ARGUMENTUMOKAT értékeli ki Haskell-ban és Clean-ben: alfüggvény/paraméter!-el való megjelölése squareinc 7 = square (inc 7) = square (1 + 7) = square 8 = 8 * 8 = 64 1.3 Curry-zés Matematikában: több argumentumot elfogadó függvény átalakítása függvények sorozatára amik csak egy-egy argumentumot kapnak Minden függvény csak egy argumentummal rendelkezik ((+) x) y -- x + y helyett 1.4 Magasabbrendű függvények Függvények, melyeknek argumentumaik egy- vagy több függvény vagy visszatérési értékük egy függvény applyfunctiontwice :: (Int -> Int) Int -> Int applyfunctiontwice f x = f(f x) 3

applyfunctiontwice (\x -> x + x) 3 = 12 1.5 Listák Listák ábrázolása Láncolt listákkal Maga a listaábrázolás is egy függvény. Funkcionális programozásban mindennek az alapja a függvény. [] listaépítés függvénye, listakonstruktor ([a] írható [] a -ként is, mint [] függvény alkalmazása) : listaragasztás, konkatenáció függvénye Listaműveletek esetén nem írunk felül semmit, NEM MÓDOSÍTUNK ELEMET! Listafüggvény eredménye egy új lista lesz Immutable, mindig másolódik (valójában csak a lista váza másolódik) Figure 1: Lista felépítése és ábrázolása funkcionális nyelvekben. Listakonstruktor mintaillesztést használ: -- "a" bármilyen típusú (polimorf) paraméter. data [] a = [] -- Üres lista ha nem adunk elemet. a : [a] -- Értékhez hozzáragasztunk egy következő listát. -- A következő lista lehet üres is ([]). Lista típus definíciója Haskell-ban: data List a = Nil -- Üres lista. Cons a (List a) -- "Cons" a ragasztás, "(List a)" lehet üres is Ez egy rekurzív, paraméteres típus Szétszedhető, újra összeragasztható, az elejéről könnyű kivenni, könnyű hozzátenni Végére nehéz elemet tenni, költségesen végig kell járni 4

(Megjegyzés: mint ahogy láncolt listákban szokás imperatív programozásban is.) Szabványos listafüggvények (Clean nyelv) Figure 2: Head, Tail, Last és Init függvények Head: lista első elemének olvasása hd [x : xs] = x -- Minteillesztés első elemre hd [] = abort "hd of []" -- Üres lista esetén hiba Tail: lista végéről olvasás Nem egy elemet, hanem a maradék listát adja vissza tl [x : xs] = xs -- Minteillesztés első elem után ragasztott listára tl [] = abort "tl of []" -- Üres lista esetén hiba Last: lista utolsó elemének olvasása (head ellentétje) last [x] = x -- Minteillesztés egy elemre last [x : xs] = last xs -- Rekurzív hívás maradék listára amíg egy elemet -- nem kapunk last [] = abort "last of []" -- Üres lista esetén hiba Init: lista elejének olvasása (tail ellentéte) init [] = [] -- "I didn't do anything and I still got paid." init [x] = [] -- Utolsó elem a listában már nem kell init [x : xs] = [x : init xs] -- Rekurzív hívás amíg egy elem nincs a listában Length: lista hossza length [] = 0 -- Minteillesztés üres listára length [_ : xs] = 1 + length xs -- "_" a thunk-ot ("tönk") jelenti. Tökmindegy -- mi van ott, nem kerül kiértékelésre, nem -- foglalkozunk vele. 5

Reverse: NEM FORDÍTJA MEG A MEGLÉVŐ LISTÁT! Másolatot készít, ami meg van fordítva. Sort: NEM RENDEZI A MEGLÉVŐ LISTÁT! Másolatot készít, ami rendezve van. Magarabbrendű listafüggvények Filter: megadott logikai függvény (predikátum, predicate) alapján kiválogatja azokat az elemeket a listából amelyekre teljesül a logikai függvény evennumberfunction :: Int -> Bool evennumberfunction x = x mod 2 == 0 evennumbers = filter (evennumberfunction) [0..] Map: elemenkénti függvényalkalmazás Első paraméter: függvény, amit map a második paraméterben kapott lista elemeire alkalmaz Második paraméter: lista, aminek elemeire az első paraméterben kapott függvényt alkalmazza map :: (a -> b) [a] -> [b] map f [] = [] map f [x : xs] = [f x : map f xs] Fold: elemenkénti fogyasztás Paraméterként kapott függvénnyel kicseréli a lista összeragasztó függvényt (:) Van jobbasszociatív (foldr) és balasszociatív (foldl) változata foldr :: (a -> b -> b) -> b -> [a] -> b -- (a -> b -> b): Alkalmazandó listafüggvény foldr f z [] = z -- b: Kezdőérték ami nincs listában foldr f z (x : xs) = f x (foldr f z xs) -- [a]: Lista amire fold alkalmazva va -- b: Eredményérték További magasabbrendű listafüggvények: takewhile: elemek megtartása míg predikátum teljesül dropwhile: elemek eldobása míg predikátum teljesül 1.6 Tisztaság Nyelvi elemei felhasználásánál mellékhatások biztosan nem lépnek fel (pure programming) Az előző értéket megsemmisítő értékadás vagy más imperatív programozásra jellemző nyelvi elem nem áll rendelkezésre Pár tulajdonság: 6

Hivatkozási helyfüggetlenség Ugyanannak a kifejezésnek a programszöveg bármely pontján = ugyanaz lesz a végeredménye Egyenlőségi érvelés Minden egyes előforduláshoz beírható a végeredmény = hisz úgy is egyenlőek a hivatkozási helyfüggetlenség miatt Egyéb tulajdonságok: Szigorú típusosság Kevés, vagy egyáltalán nincs implicit típuskonverzió Statikus típusrendszer A kifejezések típusa fordítási időben ismert Absztrakt- és algebrai adattípusok leírásához adottak a nyelvi eszközök Hindley Milner-féle korlátozottan polimorfikus típusrendszer Rekurzió, mintaillesztés Konstruktorokra, típusértékekre (amelyek valójában konstruktorok, konstans függvények) Joker minta Őrfeltételek (argumentumokra, x when x > 10) Margó-szabály Összetartozó kifejezések csoportjának azonosítására és deklarációk hatáskörének korlátozására alkalmas a bal oldali margó szélességének változtatása IO-modell Haskell IO monádja Vagy a Clean Unique World típusa (egyszeresen hivatkozott, egyedi környezet) A műveletek láncolásával (>>=, bind) egy rejtett változó, a külvilág modellje adódik át 2.Típusok 2.1 Algebrai adattípusok Algebrai adattípusok: összetett típusok amiket több típusból kapjuk Példák: List: Nil, Cons és List-ből épül fel Tree: Node, Leaf és Tree-ből épül fel De mitől algebrai egy algebrai adattípus? Típuselméletből: összeg típusok (sum types) szorzat típusok (product types) 7

Összeg típus: A B, választás, A és B altípus egy összeg típust alkot (mintha A + B lenne) Szorzat típus: A B együtt, kombináció, A és B altípus egy szorzat típust alkot (mintha A B lenne) Paraméteres algebrai adattípusok Fa (egyparaméteres algebrai típus) Ez a paraméter most az a lesz Típus definiálása data Tree a = Node a (Tree a) (Tree a) Leaf Jelölések: Tree: alaptípus a: típusváltozó Node: adatkonstruktor (ragasztó, fordító lefoglal neki memóriát) (Tree a): leszármazott típus, lehet Tree Int vagy Tree String is Típus használata fa = Node 2 (Node 1 Leaf Leaf) (Node 3 Leaf Leaf) Lehet akár két különböző típusparamétere, a és b, ekkor kétparaméteres lesz data Tree a b = Node b (Tree a b) (Tree a b) Leaf a -- most Leaf-ben is tárolok értéket Paraméternélküli adattípus Nem adok típusváltozót paraméterként Ilyen például a felsorolásos típus (enumeration) Tipikusan összeg típusokból áll data Day = Mon Tue Wed Thu Fri Sat Sun Day típuskonstruktornak hét darab adatkonstruktora van Rekurzív adattípusok Olyan adattípus, ami saját magát is tartalmazza más értékkel data List a = Cons a (List a) Nul Lista adatkonstruktorai Nul: üres lista ([]) Cons: összeragasztott lista (:) 8

Más adattípusok felírása Például parser-ek írásához kifejezésfákat (parse tree) BNF-formában megadhatjuk :: Statement = Skip Sequence Statement Statement Assign Var ArithmeticExpression If BoolExpression Statement Statement While BoolExpression Statement 2.2 Típusosztályok Hasonló egy interfészhez Megad pár függvényt, melyet a típusnak teljesíteni kell Azt mondjuk: egy típusnak van példánya adott típusosztályra amennyiben megadtunk egy példányt (instance) és definiáltuk a megfelelő függvényeket. Van lehetőség egy függvényre megadni default implementációt a többi függvény felhasználásánál. A függvények típusdeklarációiban előfordulhatnak típusparaméterek Ezekre megadhatóak megszorítások Hiszen egyébként a paraméter helyére bármely típus behelyettesíthető lenne (ez a parametrikus polimorfizmus egyébként) A megszorításban megadható, milyen típusosztály példányokat várunk el az adott típustól. Egyes funkcionális nyelvek képesek az alapvető típusosztályok függvényeit automatikusan levezetni egy típus számára (deriving). Ezek beépített, egyszerűbb típusosztályok Eq: egyenlőség Ord: rendezés Show: sztringgé alakítás Read: beolvasás sztringből 2.3 Típuskonstruktorok Típuskonstruktor: típus felépítése és származtatása. Például List és Tree Adatkonstruktor: típuskonstruktor paramétere. Ezektől függ mi lesz a típus. Nulláris típuskonstruktor Ha nulla argumentuma van: nulláris típuskonstruktornak hívják (nullary type constructor) Például data Bool = True False (Haskell) Bool: típuskonstruktor True és False: két nullás adatkonstruktor 9

Unáris típuskonstruktor data Tree a = Leaf Node a (Tree a) (Tree a) Tree: típuskonstruktor 2.4 Kindok Magasabb rendű típus: típust kap argumentumként (akárcsak magasabb rendű függvényeknél) Kind: típusok, amik információt mondanak el a kapott típusról Kind of a type, avagy mi a típus típusa? Elsőrendű típus kindja (konkrét típus vagy típuskonstans): * Magasabbrendű típus kindjai (Curry-zve írjuk őket) Unáris típuskonstruktor kindja (egy típusparamétert fogad el): Bináris típuskonstruktor kindja (két típusparamétert fogad el): Kind-ok nyelvtana: K :== (K K) Kind-ok jobb asszociatívak (jobbról kezdjük a zárójelezést) = ( ) Melyik típus milyen kind-al rendelkezik? Int: * (konkrét típus) Char: * (konkrét típus) Bool: * (konkrét típus) [a]: (unáris típuskonstruktor) Mert még kell neki hogy milyen típusú lista lesz belőle Ne felejtsd el, [a] ugyanaz mint [] a List: (unáris típuskonstruktor) data List a = Nil Cons a (List a) Argumentum: milyen típusú értékek legyenek a listában és milyen típusú értéket ragasszon össze Cons Tree: (bináris típuskonstruktor) data Tree a b = Leaf a Node b (Tree a b) (Tree a b) Argumentumok: milyen típusú legyen a, majd utána milyen típusú legyen b 10

3.Monadikus programozás Módszer mellyel számításokat lehet építeni Funkcionális nyelvekben adattípus, amiben a számítások lépések láncaiként vannak definiálva Monád meghatározza hogy az összekombinált számítások hogyan alkossanak egy új számítást Három fő művelet: bind (>>=) >> return Ha nem lennének monadikus műveletek, akkor fejjel lefelé nézne ki egy program tele lambda kifejezésekkel Pure programming: funkcionális nyelvekben nincsenek mellékhatások. Monádok: Lennél szíves csinálni nekem egy mellékhatást? (Rinus Plasmeijer) Monad mint típusosztály class Monad m where return :: a -> m a (>>=) infixl 1 :: (m a) (a -> m b) -> m b (>>) infixl 1 :: (m a) (m b) -> m b (>>) m k :== m >>= \_ -> k fail :: String -> m a Amikor ezt a típuszosztályt akarjuk példányosítani >> műveletet már meg se kell adni az instance-ban, mert >>= definíciójából származtatjuk return Egyszerű típusból (a) fogja az értéket = monadikus értéket (m a) csinál belőle Értéket beemeli a monadikus környezetbe Szerencsétlen elnevezése van, semmi köze az imperatív megfelelőjéhez, nem tér vissza semmivel Bind művelet (>>=) Számítás eredményét másik akcióhoz rendeli Argumentumként vesz 11

Monadikus értéket (m a) Függvényt, mely egyszerű típusból monadikus értéket csinál (a -> m b) Visszatérési értéke újabb monadikus érték lesz (m b) Utána lambdakifejezést kell használni f >>= \x -> return x >> Bind-ból származtatott művelet Nem bind-ol semmilyen eredményt Szekvenciaként lehet felfogni Programozható pontosvesszőnek is mondják m >> k (>>) m k = m >>= \_ -> k Maybe Mellékhatás: számítás eredményének opcionalitása adható meg Exception-ök szimulálása Hiba a függvényből felfele propagálódik Ha függvény adott pontban nem értelmezhető: Nothing Ha igen: számításokat sorba is kapcsolhatjuk bind-al amíg van eredmény :: Maybe a = Just a Nothing instance Monad Maybe where return x = Just x (>>=) (Just m) k = k m (>>=) = Nothing State Mellékhatás: bármilyen típusú állapotinformációt lehet rendelni számításhoz Bemenetként állapotot kap Kiementként t típusú visszatérési értéket és egy s típusú új állapotot add Önmagában még nem monád, hanem absztrakt monád állapot típusával, s-el paraméterezhető 12

:: State s a = ST (S s a) -- Clean nyelv unst :: (State s a) -> S s a unst (ST m) = m State kétparaméteres típus, Monad csak egy nem baj, mert State kind-jait lehet Curry-zni instance Monad (State s) where -- (State s) absztrakt monád, kell még s típusa return x = ST (return_s x) (>>=) m k = ST ((unst m) bind_s (\x -> unst (k x))) List monád Lista típusára, [] típusra is felírható egy monadikus típuspéldány Listák segtíségével is lehet monadikus műveleteket ábrázolni Mellékhatás: egy monadikus akciót egyszerre több elemen lehet végrehajtani ezeket az elemeket újra listává ragasztjuk össze instance Monad [] where return x = [x] (>>=) m k = flatten [k x \\ x <- m] do jelölés Szintaktikai cukor monadikus programozásra Haskell-ban Megfelelő átírási szabályok, melyekkel olvashatóbbá tehető a program Mintha imperatívan programoznánk do { e1; e2 } -- e1 >> do { e2 } do { p <- e1; e2 } -- e1 >>= \x -> case x of p -> do { e2 } -- _ -> fail "error" do { let p = e1; e2 } -- let p = e1 in do { e2 } do { e } -- e 4.További források Egy korábbi Funkcionális Nyelvek 1 vizsga anyagom Korábbi záróvizsga tételkidolgozások http://lambda.inf.elte.hu/fp/index.xml https://wiki.haskell.org/thunk https://wiki.haskell.org/fold 13

https://wiki.haskell.org/constructor https://wiki.haskell.org/monad http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html 14