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

Hasonló dokumentumok
2016, Funkcionális programozás

2018, 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

2018, Funkcionális programozás

2018, Funkcionális programozás

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

2018, 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 GYAKORLAT JEGYZET

2016, Funkcionális programozás

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

2018, Diszkrét matematika

Szkriptnyelvek. 1. UNIX shell

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

Tulajdonságalapú tesztelés

Feldspar: Nyelv digitális jelfeldolgozáshoz

Funkcionális Nyelvek 2 (MSc)

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi.

Funkcioná lis prográmozá s Start

2018, Diszkre t matematika. 8. elo ada s

2016, Diszkrét matematika

Funkcionális programozás

Imperatív programozás

1. Alapok. #!/bin/bash

Bevezetés a programozásba I.

Python tanfolyam Python bevezető I. rész

2018, Diszkrét matematika

file./script.sh > Bourne-Again shell script text executable << tartalmat néz >>

Adatszerkezetek és algoritmusok

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

2018, Diszkrét matematika

2016, Diszkrét matematika

Bevezetés a Python programozási nyelvbe

Matematikai programok

2019, Diszkrét matematika. 1. el adás

2016, Diszkrét matematika

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

2015, Diszkrét matematika

Funkcionális nyelvek Király, Roland

S2-01 Funkcionális nyelvek alapfogalmai

Matematikai programok

Adattípusok, vezérlési szerkezetek. Informatika Szabó Adrienn szeptember 14.

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

Karakterkészlet. A kis- és nagybetűk nem különböznek, a sztringliterálok belsejét leszámítva!

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

Oktatási segédlet 2014

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós február 18. Széchenyi István Egyetem, Gy r

2017, Diszkrét matematika

Programozás I gyakorlat

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

1. Egészítsük ki az alábbi Python függvényt úgy, hogy a függvény meghatározza, egy listába, az első n szám faktoriális értékét:

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

2018, Diszkrét matematika

Operációs rendszerek. 9. gyakorlat. BASH recap, reguláris kifejezések UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

AWK programozás, minták, vezérlési szerkezetek

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

FUNKCIONÁLIS PROGRAMOZÁS

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

Adatbázis-kezelés ODBC driverrel

2016, Diszkrét matematika

7. Laboratóriumi gyakorlat: Vezérlési szerkezetek II.

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

LUSTA KIÉRTÉKELÉS, LUSTA LISTA

BASH SCRIPT SHELL JEGYZETEK

Bisonc++ tutorial. Dévai Gergely. A szabály bal- és jobboldalát : választja el egymástól. A szabályalternatívák sorozatát ; zárja le.

Programozási nyelvek JAVA EA+GY 1. gyakolat

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

Delphi programozás I.

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

AWK programozás, minták, vezérlési szerkezetek

Programozási módszertan. Mohó algoritmusok

BABEŞ-BOLYAI TUDOMÁNYEGYETEM MATEMATIKA-INFORMATIKA KAR Felvételi verseny - minta Informatika írásbeli

Imperatív programozás

A Feldspar fordító, illetve Feldspar programok tesztelése

Tartalomjegyzék. I. Tillárom 3

INFORMATIKA javítókulcs 2016

Komputeralgebra Rendszerek

S z á m í t ó g é p e s a l a p i s m e r e t e k

INFORMATIKA tétel 2018

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

Operációs rendszerek. 9. gyakorlat. Reguláris kifejezések - alapok, BASH UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

Operációs rendszerek. 11. gyakorlat. AWK - szintaxis, vezérlési szerkezetek UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

C programozási nyelv

Gyakorló feladatok Gyakorló feladatok

BABEŞ BOLYAI TUDOMÁNYEGYETEM MATEMATIKA ÉS INFORMATIKA KAR BBTE Matek-Infó verseny 1. tételsor INFORMATIKA írásbeli. A versenyzők figyelmébe:

Digitális elektronika gyakorlat. A VHDL leírástípusok

Smalltalk 2. Készítette: Szabó Éva

Apple Swift kurzus 3. gyakorlat

Programozás 6. Dr. Iványi Péter

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Előfeldolgozó rendszer Tömbök. Dr. Bécsi Tamás 4. Előadás

SCILAB programcsomag segítségével

8. Laboratóriumi gyakorlat: Bevezetés a reguláris kifejezések használatába

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

Informatika 1 2. el adás: Absztrakt számítógépek

INFORMATIKA tétel 2019

Matlab alapok. Baran Ágnes. Baran Ágnes Matlab alapok Elágazások, függvények 1 / 15

Programozás C és C++ -ban

Függvények. Programozás I. Hatwágner F. Miklós november 16. Széchenyi István Egyetem, Gy r

Átírás:

Funkcionális programozás 4. el adás Sapientia Egyetem, Matematika-Informatika Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2019, tavaszi félév

Mir l volt szó? GHC parancsok fenntartott szavak könyvtármodul importálása A Haskell további jellemz i: feltételek egymásba ágyazása a let...in, where kifejezések a case...of kifejezés függvénykompozícíó függvénykiértékelés a $ szimbólummal a $ és a. szimbólumok a tuple típus, könyvtárfüggvények a lista típus, könyvtárfüggvények operátorok, függvények listákon

Mir l lesz szó? a Haskell kiértékelési stratégiája függvények listákon: map, null, lter, reverse take, takewhile, drop, dropwhile, elem, zip, splitat, iterate, repeat, replicate, any, all Haskell modulok, kompilálás

A Haskell kiértékelési stratégiája funkcionális programozási nyelvek esetén kétféle kiértékelési stratégiát ismerünk: lusta (lazy), mohó (eager) a Haskell kiértékelési stratégiája lusta, Lusta kiértékelési stratégia: a legbaloldalibb, legküls redex (redukálható kifejezés) helyettesítése történik el ször, egy alkifejezés csak akkor értékel dik ki, ha szükség van az értékére (ha a kifejezés függvénymegadással kezd dik el bb a függvénydeníció lesz alkalmazva) ez a stratégia mindig megtalálja a normál formát, ha az létezik Pl. Clean, Haskell, Miranda lehetségessé válik a függvények kötetlen deniálása: egy függvény akkor is képes értéket visszaadni, ha egyik argumentuma nem deniált, lehetségessé válik a végtelen adatszerkezetek létrehozása, a mohó kiértékelési stratégiához képest kevésbé hatékony.

A mohó (eager) kiértékelési stratégia a legbaloldalibb, legbels redex, az argumentumok helyettesítése történik meg el ször, nem mindig ér véget a kiértékelési folyamat, hatékonyabb mint a lusta rendszer, Pl. Lisp, SML, Hope, a lusta kiértékelési stratégia hatékonyságát oly módon lehet javítani, hogy az azonos részkifejezéseket megjelöljük, az eredményt megjegyezzük és ahányszor szükség van rá mindig a megjegyzett eredményt használjuk.

Példa, kiértékelési stratégiákra my_inc :: Num a => a -> a my_inc x = x + 1 negyzet :: Num a => a -> a negyzet x = x * x negyzet_inc :: Num a => a -> a negyzet_inc x = negyzet (my_inc x) > negyzet_inc 6 A lusta kiértékelési stratégia: negyzet_inc 6 -> negyzet(my_inc 6) -> (my_inc 6) * (my_inc 6) -> (6 + 1) * (6 + 1) -> 7 * 7 -> 49 A mohó kiértékelési stratégia: negyzet_inc 6 -> negyzet(my_inc 6) -> negyzet(6 + 1) -> negyzet(7) -> 7 * 7 -> 49 ÁRTON Gyöngyvér

1. feladat Határozzuk meg egy lista második elemét second :: [a] -> a second [] = error "ures lista" second [k1] = error "egy elemu" second (k1: k2: ve) = k2 > second [1..10] 2

map :: (a -> b) -> [a] -> [b] A paraméterként megadott függvényt alkalmazza a második paraméterként megadott lista minden elemére. > map (2^) [0..10] [1,2,4,8,16,32,64,128,256,512,1024] my_map1 :: (a -> b) -> [a] -> [b] my_map1 f [] = [] my_map1 f (k: ve) = f k: my_map1 f ve > import Data.Char > my_map1 toupper "abcdefghijklmnop" "ABCDEFGHIJKLMNOP" > my_map1 length ["abcd", "efg", "hijkl"] [4,3,5]

null :: [a] -> Bool A null függvény benne van a standard könyvtárban és megvizsgálja hogy egy lista üres lista-e vagy tartalmaz elemeket. my_null :: [a] -> Bool my_null [] = True my_null (k: ve) = False A null függvény segítségével a map függvény 2. verziója: my_map2 :: (a -> b) -> [a] -> [b] my_map2 f ls = if null ls then [] else (f (head ls)): my_map2 f (tail ls)

2. feladat Adott listabeli elemekre határozzuk meg a páros osztók listáját. paroso :: (Integral a) => a -> (a, [a]) paroso n = (n, [i i <- [2, 4.. (n `div` 2 + 1)], n `rem` i == 0]) > paroso 60 (60,[2,4,6,10,12,20,30]) > my_map2 paroso [50..59] [(50,[2,10]),(51,[]),(52,[2,4,26]),(53,[]),(54,[2,6,18]), (55,[]),(56,[2,4,8,14,28]),(57,[]),(58,[2]),(59,[])]

filter :: (a -> Bool) -> [a] -> [a] Kiválasztja a lista azon elemeit melyek eleget tesznek egy adott feltételnek. > filter isdigit "abcd123rfg456hij" "123456" my_filter1 :: (a -> Bool) -> [a] -> [a] my_filter1 f [] = [] my_filter1 f (k: ve) f k = k: my_filter1 f ve otherwise = my_filter1 f ve > my_filter1 even [1..10] [2,4,6,8,10] > my_filter1 (>0) [10,-5,3,-12,7] [10,3,7]

my_filter kódsor, 2. verzió: my_filter2 :: (a -> Bool) -> [a] -> [a] my_filter2 f ls = let k = head ls ve = tail ls in if null ls then [] else if f k then k: my_filter2 f ve else my_filter2 f ve > import Data.Char > my_filter2 isupper "EMTE-Sapientia" "EMTES"

reverse :: [a] -> [a] megfordítja a lista elemeit > reverse [1..10] [10,9,8,7,6,5,4,3,2,1] my_reverse1 :: [a] -> [a] my_reverse1 [] = [] my_reverse1 (k: ve) = my_reverse1 ve ++ [k] my_reverse2 :: [a] -> [a] my_reverse2 ls = if null ls then [] else my_reverse2 (tail ls) ++ [head ls] > my_reverse1 "helovilag" "galivoleh"

megfordítja a lista elemeit, harmadik verzió my_reverse3 :: [a] -> [a] my_reverse3 ls = my_sreverse3 ls [] where my_sreverse3 [] res = res my_sreverse3 (k : ve) res = my_sreverse3 ve (k: res) > my_reverse3 "helovilag" "galivoleh"

take :: Int -> [a] -> [a] Visszatéríti a második argumentumként megadott lista els n elemét, ahol n a függvény els argumentuma. > take 3 ["abc", "efgh", "ijklmn", "op", "qrst"] ["abc","efgh","ijklmn"] > take 10 ["abc", "efgh", "ijklmn", "op", "qrst"] ["abc","efgh","ijklmn","op","qrst"] > take 10 [ 1/i i <- [1..]] [1.0,0.5,0.3333333333333333,0.25,0.2,0.16666666666666666, 0.14285714285714285,0.125,0.1111111111111111,0.1] > take 10 [ 1/(2^i) i <- [1..]] > [0.5,0.25,0.125,6.25e-2,3.125e-2,1.5625e-2,7.8125e-3,3.90625e-3, 1.953125e-3,9.765625e-4]

my_take kódsor, 1. verzió: my_take1 :: Int -> [a] -> [a] my_take1 n [] = [] my_take1 n (k: ve) n == 0 = [] otherwise = (k: my_take1 (n-1) ve) > my_take1 10 [] [] > my_take1 10 ["abc", "efgh", "ijklmn", "op", "qrst"] ["abc","efgh","ijklmn","op","qrst"]

my_take kódsor, 2. verzió: my_take2 :: Int -> [a] -> [a] my_take2 n ls = let k = head ls ve = tail ls in if null ls then [] else if n == 0 then [] else k: my_take2 (n - 1) ve > my_take2 4 "Sapientia 2017" "Sapi"

takewhile :: (a -> Bool) -> [a] -> [a] Visszatéríti a második argumentumként megadott lista azon prexét, amelyben az elemek eleget tesznek a feltételnek. > takewhile even [2,4,6,8,9,10,12,14] [2,4,6,8] my_takewhile1 :: (a -> Bool) -> [a] -> [a] my_takewhile1 f [] = [] my_takewhile1 f (k: ve) f k = (k: my_takewhile1 f ve) otherwise = [] > my_takewhile1 ( >0 ) [1,2,3,-5,4,6,7] [1,2,3] > import Data.Char > takewhile1 isdigit "1234aedbcde567fgh" "1234"

my_take kódsor, 2. verzió: my_takewhile2 :: (a -> Bool) -> [a] -> [a] my_takewhile2 f ls = if null ls then [] else if f k then k: my_takewhile2 f ve else [] where k = head ls ve = tail ls > length (my_takewhile2 ( /= 0) [1 / (2 ^ i) i <-[1..]]) 1023

drop :: Int -> [a] -> [a] Kitörli a második argumentumként megadott lista els n elemét, ahol n a függvény els argumentuma. > drop 3 ["abc", "efgh", "ijklmn", "op", "qrst"] ["op","qrst"] my_drop :: Int -> [a] -> [a] my_drop n [] = [] my_drop n (k: ve) n == 0 = (k: ve) otherwise = my_drop (n-1) ve > my_drop 10 [] [] > my_drop 10 ["abc", "efgh", "ijklmn", "op", "qrst"] []

dropwhile :: (a -> Bool) -> [a] -> [a] Kitörli a második argumentumként megadott lista azon prexét, amelyben az elemek eleget tesznek a feltételnek. > dropwhile even [2,4,6,8,9,10,12,14] [9,10,12,14] my_dropwhile :: (a -> Bool) -> [a] -> [a] my_dropwhile f [] = [] my_dropwhile f (k: ve) f k = my_dropwhile f ve otherwise = (k: ve)

elem ::(Eq a) => a -> [a] -> Bool Megvizsgálja, hogy egy adott elem szerepel-e a listaelemek között. > elem 'a' "Sapientia University" True > elem 'A' "Sapientia University" False my_elem :: (Eq a) => a -> [a] -> Bool my_elem x [] = False my_elem x (k: ve) x == k = True otherwise = my_elem x ve maganhangzo :: Char -> Bool maganhangzo c = elem c "aeiouaeiou" > my_dropwhile maganhangzo "aedbcdeamiu" "dbcdeamiu"

zip :: [a] -> [b] -> [(a, b)] A bemeneti két lista alapján elempárokból álló listát hoz létre. Az új lista elemszámát a rövidebb lista elemszáma határozza meg. > zip ["abc", "efg"] [1,2,3,5,6,7] [("abc",1),("efg",2)] my_zip :: [a] -> [b] -> [(a, b)] my_zip [] [] = [] my_zip [] li = [] my_zip li [] = [] my_zip (k1: ve1) (k2: ve2) = ((k1, k2): my_zip ve1 ve2) > zip [1..8] "abcdefghijklmn" [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h')]

splitat :: :: Int -> [a] -> ([a], [a]) A megadott indexérték alapján a bemeneti listát két listára osztja. Az eredmény egy tuple. > splitat 4 [1,2,3,4,5,6,7,8,9] ([1,2,3,4],[5,6,7,8,9]) my_splitat :: Int -> [a] -> ([a], [a]) my_splitat n list = (l1, l2) where l1 = take n list l2 = drop n list > my_splitat 10 "Sapientia University" ("Sapientia ","University")

iterate :: (a -> a) -> a -> [a] Alkalmazza a megadott függvényt kiindulva a kezdeti értékként megadott paraméterb l. > take 10 (iterate (\x -> 2 * x ) 1) [1,2,4,8,16,32,64,128,256,512] repeat :: a -> [a] A megadott elemmel egy végtelen listát határoz meg. > take 5 (repeat "hello") ["hello","hello","hello","hello","hello"] replicate :: Int -> a -> [a] A megadott elemmel egy n elem listát határoz meg. > replicate 5 "hello" ["hello","hello","hello","hello","hello"]

any :: (a -> Bool) -> [a] -> Bool Megvizsgálja, hogy a megadott feltételt teljesíti-e valamelyik listabeli elem. > any isupper "Sapientia University" True all :: (a -> Bool) -> [a] -> Bool Megvizsgálja, hogy a megadott feltételt teljesíti-e minden listabeli elem. > all isupper "Sapientia University" False

Haskell modulok Nagyobb program esetén a projektet részekre kell bontani, ezeket a részegységeket hívjuk moduloknak (más programozási nyelvben is így van). A modul els sora a module kulcsszót és a module nevét tartalmazza, nagy kezd bet vel, utána a where kulcsszó, majd az importok és a további kódsorok következnek: -- filename: Eloadas5.hs -- author: Marton Gyongyver -- date: 11.03.2015 module Eloadas5 where import Eloadas3 import Data.Char import Data.List Egy állományba csak egy modult írjunk.

Haskell modulok Ha a modulok függetlenek, akkor lehet egy projektet készíteni. module Main where import Eloadas3 import Eloadas4 import Eloadas5 import Data.Char import Data.List main = print (convert16 458729) Minden modulban importalni kell azt a modult, amelyben annak a függvénynek a deniciója van, amit szeretnénk használni.

Haskell modulok, komplilálás A parancssorból való futtatást több lépésb l oldjuk meg: 1. lépés: a megfelel f modul (Main) betöltése: : load Main.hs 2. lépés: az értelmez ben ha megakarom hívni: > main 6FFE9 3. lépés: a f modul kompilálása, az exe létrehozása windows alatt: :! ghc --make "Main.hs" -o main.exe 4. lépés: ezután lehet futtatni parancssorból is