128
Funkcionalno programiranje specijalno izdanje, akademska godina 2016/17 Matematiˇ cki fakultet Ivan ˇ Cuki´ c [email protected] http://poincare.math.rs/-ivan

Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

  • Upload
    lamanh

  • View
    242

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funkcionalno programiranjespecijalno izdanje, akademska godina 2016/17

Matematicki fakultet

Ivan Cukic

[email protected]://poincare.math.rs/-ivan

Page 2: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

UVOD

Page 3: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funkcionalno programiranje

Sta je funkcionalno programiranje?

3

Page 4: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Osobine FP jezika

funkcije viseg reda

cistocalenjoststroga tipiziranost

Ako uzmemo sve ovo kao preduslov da jezik bude funkcionalan,vecina jezika ce otpasti.

4

Page 5: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Jezici

Lisp – prvi funkcionalni jezikHaskell – danasnji sinonim za FPScala – mesavina OO i FP paradigmiErlang – jezik za distribuirane sistemeElm – jezik za pisanje veb aplikacijaC++ – najpopularniji funkcionalni jezik :)

5

Page 6: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

SADRZAJ KURSA

Page 7: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Uvod: Haskell

lenjostkarijevanje i parcijalna aplikacijafunkcije viseg redamap, filter, foldpattern matching. . .

7

Page 8: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

C++

Razlike izmedju normalnih FP jezika i C++-aIntervali, transformacije intervalaMonade, optional/maybe, . . .Primena monada u parsiranju, . . .Dizajn softvera kroz reaktivne tokove

8

Page 9: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Obaveze tokom godine

Jos uvek nije nista precizirano – dok se ne vidi koliko ce bitiprijavljenih studenata.

Projekat, kolokvijum, ispit?

9

Page 10: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

SCALA

Page 11: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Java

Nastala sa idejom da bude jednostavnaEkosistem se razvijao, platforma i bibliotekeJezik je vecinom stagnirao, ili je prosirivan na cudne nacine

11

Page 12: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Scala i Java

Rade na JVMScala moze da poziva metode iz Java, vecinom i obratnoSkala je ekspresivniji jezik, sa (vecinom) dobrimpodrazumevanim ponasanjemSkala nema staticke metode i promenljive

12

Page 13: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Kompilacija Scala programa

scalac program.scala # pravi .class fajl, kao javac

scala # pokrece Scala REPLscala program.scala # pokrece programscala Program # pokrece program, kao java

sbt compile # kompajlira projekatsbt run # pokrece projekat

13

Page 14: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Scala kao jezik

Syntactic sugarPametni tipovi umesto primitivnihStriktni tipoviPomoc i u imperativnom programiranju (foreach,try-with-resource, exceptionless)

14

Page 15: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Lose strane

Prebrza evolucijaNedovoljna kompatibilnost unazad

15

Page 16: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Kursevi

Functional Programming Principles in Scala

Functional Program Design in Scala

16

Page 17: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

CAS 1: HASKELL – OSNOVE, TIPOVIPODATAKA

Page 18: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Implementacije Haskella

Postoje mnoge implementacije jezika Haskell:

GHC – Glasgow Haskell CompilerUHC – Ultrecht Haskell CompilerLHC – LLVM Haskell Compiler. . .Hugs

18

Page 19: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Ekstenzije jezika

Prirodna evolucija jezika – kompajleri implementiraju ekstenzijekoje ako se pokazu korisnim mogu kasnije da postanu deosamog jezika.

Neke od interesantnih ekstenzija

OverloadedStringsLambdaCase. . .

19

Page 20: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Kompilacija Haskell programa

ghc program.hs # kompajlira program,# fajl mora da ima main funkciju

Flegovi:

-Wall # upozorenja na potencijalne greske-Werror # sva upozorenja postaju greske

--make # kompajlira projekat sa vise modula

-o # izlazni fajl

-XEkstenzija # ukljucuje ekstenziju jezika

20

Page 21: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

REPL – read–eval–print loop

ghci # pokrece haskell REPLghci program.hs # pokrece REPL i ucitava funkcije

# iz datog fajla

:module Modul # ucitava modul (biblioteku f-ja)

:set +t # za svaki rezultat ispisuje i tip:set +m # viselinijske definicije

:set -XEkstenzija # ukljucuje navedenu ekstenziju

Podesavanja se nalaze u ~/.ghci

21

Page 22: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Cabal – sistem za kompilaciju projekata

cabal sandbox init # inicijalizuje "igraliste"cabal ini # pravi haskell projekatcabal configure # priprema projekat za kompilacijucabal build # kompajlira projekat

Alternativa: stack

22

Page 23: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Liste

[] -- prazna lista(x: xs) -- definisanje liste

-- x je glava, xs je 'rep'

[ 1, 2, 3 ] -- sintaksa za 1 : 2 : 3 : [][ True, False ] -- lista logickih vrednosti

23

Page 24: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Liste brojeva

[ 1 .. 5 ] -- [ 1, 2, 3, 4, 5 ][ 1, 3 .. 10 ] -- [ 1, 3, 5, 7, 9 ][ 5, 4 .. 1 ] -- [ 5, 4, 3, 2, 1 ][ 1 .. ] -- beskonacna lista

24

Page 25: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Stringovi

data String = [Char]

"Fun" -- [ 'F', 'u', 'n' ]'f' : "un" -- "Fun""f" ++ "un" -- "Fun"

U ozbiljnijim projektima, koristiti Data.Text iliData.ByteString tipove uz -XOverloadedStringsekstenziju jezika.

25

Page 26: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Ciklicna lista

Implementirati funkcije za baratanje ciklicnom listom:

insert – dodaje element kao trenutniswap – zamenjuje trenutni element sledecimremove – uklanja trenutni elementtoNext – pomera glavu na sledeci elementtoPrev – pomera glavu na prethodni element

26

Page 27: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Ciklicna lista – pokusaj 1

Koristimo [Int] da reprezentujemo listu

insert :: Int -> [Int] -> [Int]insert value list = (???)

27

Page 28: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Ciklicna lista – pokusaj 1

swap :: [Int] -> [Int]swap = (???)

28

Page 29: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Ciklicna lista – pokusaj 1

swap :: [Int] -> [Int]swap [] = []swap [x] = [x] -- sta ako uklonimo ovaj red?swap (x1:x2:xs) = x2:x1:xs

29

Page 30: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Ciklicna lista – pokusaj 1

swap :: [Int] -> [Int]swap (x1:x2:xs) = x2:x1:xsswap xs = xs

30

Page 31: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Ciklicna lista – pokusaj 1

swap :: [Int] -> [Int]swap xs = case xs of

[] -> [][x] -> [x](x1:x2:xs) -> x2:x1:xs

31

Page 32: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Tipovi

Sta su tipovi sledecih vrednosti?

[True, False][1, 2, 3][]

32

Page 33: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Korisnicki tipovi

Ako zelimo da imenujemo neki postojeci tip, koristimo typekljucnu rec:

-- Imena tipova pocinju velikim slovomtype Ring = [Int]

insert :: Int -> Ring -> Ringswap :: Ring -> Ring

Na ovaj nacin krijemo internu implementaciju od korisnika nasebiblioteke.

33

Page 34: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Genericki tipovi

Do sada smo imali samo ciklicne liste celih brojeva.

Sta ako zelimo da dozvolimo korisniku da pravi ciklicne listeproizvoljnog tipa? (kao sto bi u C++-u i Javi bio Ring<T>)

-- Tipske promenljive pocinju malim slovomtype Ring t = [t]

insert :: t -> Ring t -> Ring tswap :: Ring t -> Ring t

34

Page 35: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Rotiramo listu

type Ring t = [t]

focusNext :: Ring t -> Ring tfocusNext = (???)

35

Page 36: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Operacije kontrukcije i konkatenacije

:t (:):t (++)

36

Page 37: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Implementacija konkatenacije

(++) :: [a] -> [a] -> [a][] ++ ys = ys(x:xs) ++ ys = x : (xs ++ ys)

Rekli smo da ne zelimo vise da vidimo rekurziju. Kako ovoimplementirati koristeci fold?

37

Page 38: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Rotiramo listu na drugu stranu

type Ring t = [t]

focusPrev :: Ring t -> Ring tfocusPrev = (???)

38

Page 39: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Rotiramo listu na drugu stranu

type Ring t = [t]

focusPrev :: Ring t -> Ring tfocusPrev ts = reverse (focusNext (reverse ts))

Nije efikasno, ali je dobro za razmisljanje.

39

Page 40: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Kompozicija funkcija

(.) :: (b->c) -> (a->b) -> (a->c)(f . g) x = f (g x)

Alternativno, preko lambda funkcije.

40

Page 41: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Operator aplikacije funkcije

($) :: (a -> b) -> a -> bf $ x = f x

41

Page 42: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Efikasnost operacija nad listama

Liste u Haskelu su jednostruko povezane – glava i rep – takoda pate od svih problema koje imaju liste u drugim jezicima.

Alternativne strukture podataka: Data.Sequence,Data.Vector.

42

Page 43: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Efikasnost operacija nad listama

Brze operacije:

(:) -- O(1)head -- O(1)tail -- O(1)

Sporije operacije:

xs !! n -- O(n)take n, drop n, splitAt n -- O(n)xs ++ yz -- O(length xs)

43

Page 44: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Osnovne operacije sa listama

null -- da li je lista prazna?head last -- prvi, odnosno poslednji elementtail init -- svi osim prvog, odnosno poslednjeg

length "Hello world" -- 11reverse "Hello world" -- "dlrow olleH""Hello world" !! 4 -- 'o'

44

Page 45: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Primeri

Ekstraktovanje prve reci iz receniceEkstraktovanje prve dve reci iz receniceObrnuta varijanta mapiranja

45

Page 46: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

CAS 2: HASKELL – OSNOVNEFUNKCIJE, TESTIRANJE, KLASE

TIPOVA

Page 47: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

zip

-- zip :: [a] -> [b] -> [(a, b)]zip "Hello" "World"

Primeri:

-- Indeksiranje elemenata listewithIndex = zip [0..]

-- Racunanje parovapairs xs = zip xs $ tail xs

-- Provera da li je lista sortiranaisSorted xs = and [ x <= y | (x, y) <- pairs xs ]

47

Page 48: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

zipWith

-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]zipWith (+) [1..5] [5..]

48

Page 49: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

map

map :: (a -> b) -> [a] -> [b]

map length $ words "The silent old pond a mirror of ancient calm, a frog-leaps-in splash."let ws = words "The silent old pond a mirror of ancient calm, a frog-leaps-in splash."

in zip ws $ map length ws

49

Page 50: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

filter

filter :: (a -> Bool) -> [a] -> [a]

let ws = words "The silent old pond a mirror of ancient calm, a frog-leaps-in splash."in filter ((>5) . snd) (zip ws $ map length ws)

50

Page 51: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Fold

foldlfoldl1foldrfoldr1

51

Page 52: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Fold - primer

and :: [Bool] -> Boolconcat :: [[a]] -> [a]all :: (a -> Bool) -> [a] -> Boolany :: (a -> Bool) -> [a] -> Boollength :: [a] -> Int

(!!) :: [a] -> Int -> atakeWhile :: (a -> Bool) -> [a] -> [a]

map :: (a -> b) -> [a] -> [b]filter :: (a -> Bool) -> [a] -> [a]

52

Page 53: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Karijevanje

addNumbers (a, b, c) = a + b + c

addNumbers a b c = a + b + c

addNumbers = \ a ->\ b ->

\ c -> a + b + c

53

Page 54: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Polimorfne funkcije

head :: [a] -> a

indexOf :: Eq a => a -> [a] -> Int

isSorted :: Ord a => [a] -> Bool

54

Page 55: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Sintaksa operatora

(+) 1 2

10 mod 3

(1.0/) 4.0(/2.0) 4.0

55

Page 56: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Generatori lista (List comprehension)

Lista svih neparnih brojeva od 1 do 42

[ x | x <- [1..42], odd x ]

56

Page 57: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Testiranje cistih funkcija

Ciste funkcije su lake za testiranje – jedino sto treba dauradimo je da konstruisemo argumente koje moramo daprosledimo funkciji.

U OOP stilu programiranja, moramo da simuliramo svepotrebne delove spoljasnjeg stanja.

57

Page 58: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Testiranje fiksnih tacaka

prop_swap s = s == swap (swap s)

import Test.QuickCheckquickCheck prop_swap

58

Page 59: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Korisnicki tipovi

Do sada smo videli kako se prave aliasi postojecih tipova:

type Ring = [Int]

I videli smo sta su liste, n-torke (n-tuple).

Ali, sta kad nam je potrebno nesto naprednije?

59

Page 60: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Korisnicki tipovi – nastavak

data Bool = False | True

data Ring = MakeRing [t] [t]

data Maybe t = Nothing | Just t

60

Page 61: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Korisnicki tipovi – nastavak

Konsturktori mogu da se koriste kao funkcije da napravevrednost odredjenog tipa, ali i da dekonstruisu vrednost zapattern matching:

data Bool = False | True

toString True = "True"toString False = "False"

data Ring = MakeRing [t] [t]

ringSum (MakeRing ls rs) = sum ls + sum rs

Napomena: Konstruktori mogu da budu i operatori, ali u tomslucaju moraju da pocnu dvotackom.

61

Page 62: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Korisnicki tipovi – enkapsulacija

Ako sakrijemo konstruktore, krijemo “internu implementaciju”nase strukture.

module Ring(Ring, ringSum) where

62

Page 63: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Primer lepse implementacije Ring tipa

data Ring = MakeRing [t] [t]

(videti primer sa casa)

63

Page 64: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Klase tipova (type classes)

Zelimo da uklonimo vrednost iz liste

remove :: Ring t -> t -> Ring t

Da li mozemo ovo da implementiramo za bilo kakvo t?Da li mozemo da implementiramo sortiranje liste bilo kakviht-ova?

64

Page 65: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Klase tipova (type classes)

Da bismo poredili vrednost nekog t-a sa datim, tip t mora daima implementiran operator ==:

remove :: Eq t => Ring t -> t -> Ring t

Da bismo mogli da sortiramo listu, elementi liste moraju daimaju implementirano poredjenje:

sort :: Ord t => [t] -> [t]

65

Page 66: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Klase tipova (type classes)

Kako se definisu klase tipova?

class Num a where(+) :: a -> a -> a(*) :: a -> a -> aneg :: a -> a-- ...

Kad zelimo da kazemo da nas tip pripada ovoj klasi, mozemo dadefinisemo ove funkcije:

instance Num Int wherea + b = -- implementiramo sabiranjea * b = -- ...neg a = -- ...-- ...

66

Page 67: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Kako rade klase tipova? (konceptualno)

Kad napisemo nesto ovako:

square :: Num n => n -> nsquare x = x * x

Kompajler interno generise nesto slicno sledecem:

square :: Num n -> n -> nsquare m x = (*) m x x

m je vrednost tipa Num n – i razlicita je za svako n. Ovo mozeda se gleda kao da je square mapa funkcija – mapira vrednostikoje predstavljaju identifikator tipa na funkcije koje pripadajutom tipu.

67

Page 68: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Kako rade klase tipova? (konceptualno)

class Num a where data Num a = MakeNum(+) :: a -> a -> a -> (a -> a -> a)neg :: a -> a (a -> a)

instance Num Int where dNumInt :: Num Inta + b = plus a b -> dNumInt = MakeNum plusneg a = negate a negate

68

Page 69: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Kako rade klase tipova? (konceptualno)

Pri pozivu funkcije, to izgleda ovako:

-- Num n -> n -> n -> n Num n -> n -> n -> nnegSum x y = -> negSum m x y =

neg $ x + y neg m $ (+) m x y

69

Page 70: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Razlika u odnosu na OOP

Funkcije nisu vezane za vrednostPostojeci tipovi mogu da postanu instance neke nove klaseZavistnost moze da bude i od povratnog tipafromInteger :: Num a => Integer -> aStaticki polimorfizam, nije nasledjivanje

70

Page 71: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

CAS 3: HASKELL – KLASE TIPOVA, IO,TYPE KIND

Page 72: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Klase tipova (type classes)

Kako se definisu klase tipova?

class Eq a where(==) :: a -> a -> Bool(/=) :: a -> a -> Boolx == y = not (x /= y)x == y = not (x /= y)

72

Page 73: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Klase tipova (type classes)

Kako da kazemo da je nas tip Eq?

instance Eq t => Eq (Ring t) where(==) = ...

73

Page 74: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Genericke funkcije

Videli smo sta map radi za liste?Da li mozemo da je koristimo za nizove, Maybe a, . . .

map $ Just 2

74

Page 75: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Genericke funkcije

fmap ne radi samo nad listama, nego i na drugim tipovima.

class Functor f wherefmap :: (a -> b) -> f a -> f b

Uz pravila:

fmap id = idfmap (f . g) = (fmap f) . (fmap g)

75

Page 76: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Tipovi sa konverzijom u Bool

while (1) {// ...

}

Pogledati primer evil_bool

76

Page 77: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

I/O – problem komunikacije sa svetom

Formalnija definicija cistoce – referential transparency.

Kad su funkcije ciste, nema razlike koja se prva evaluira.

77

Page 78: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

I/O – stvaranje novih svetova

78

Page 79: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

I/O

Vrednost tipa IO t je akcija koja proizvodi vrednost tipa t imodifikovani svet nad kojim moze da se izvrsi naredna akcija.

main :: IO () -- vraca akciju koja-- vraca 0-tupl i novi svet

79

Page 80: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

I/O

getLine :: IO StringputStrLn :: String -> IO ()

main :: IO ()main = putStrLn "Hello world"

-- da li mozemain = putStrLn (getLine)

80

Page 81: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

I/O

main = getLine >>= putStrLn

Ili upotrebom do notacije:

main = do { line <- getLine; putStrLn line}

81

Page 82: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

I/O

Promenljiva moze samo jednom da dobije vrednost

main = do { line <- getLine; line <- getLine -- definise novu prom.; -- ...}

82

Page 83: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

C i Haskell

do { x <- e; s } = e >>= (\x -> do { s })do { e } = e

(>>=) :: IO a -> (a -> IO b) -> IO b

83

Page 84: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Razmotavanje do notacije

echo :: IO ()echo = do { line <- getLine; putStrLn line }

postaje

echo = getLine >>= (\ line -> putStrLn line }

sto je isto sto i

echo = getLine >>= putStrLn

84

Page 85: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Vracanje vrednosti u IO

getTwoLines :: IO (String, String)getTwoLines = do { line1 <- getLine

; line2 <- getLine; return (line1, line2)}

return :: a -> IO a

echo = getLine >>=(\ line1 -> getLine >>=

(\ line 2 -> return (line1, line2)))

85

Page 86: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Frekvencija reci

Zadatak: Napisati program koji za dati fajl racuna brojpojavljivanja svake reci. Izlaz sortirati pocevsi od najcescekoriscenih reci.

Knutovo resenje za casopis Communications of ACM jezauzimalo desetak strana dokumentovanog koda u Paskalu.

Resenje Daga Mekilroja

tr -cs A-Za-z '\n' |tr A-Z a-z |sort |uniq -c |sort -rn |set ${1}q

86

Page 87: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Type kind

Konstruktori tipova proizvode nove tipove na osnovupostojecih. Dosta nalik obicnim funkcijama.

:k IntInt :: *

:k MaybeMaybe :: * -> *

:k EitherEither :: * -> * -> *

:k Maybe IntMaybe Int :: *

87

Page 88: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

CAS 4: HASKELL – GLOSS –BIBLIOTEKA ZA 2D GRAFIKU

Page 89: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Osnovni prikaz

--| Funkcija za prikaz staticke slikedisplay :: Display -- prozor

-> Color -- boja pozadine prozora-> Picture -- slika koju treba prikazati-> IO ()

main = let window = InWindow (400, 400) (20, 20)background = whiteview = circle 40

in display window background view

89

Page 90: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Neke osnovne funkcije

Crtanje:

polygon -- crta konveksan poligonline -- crta poligonalnu linijulineLoop -- crta zatvorenu pol. linijucircle -- crta krug

png -- ucitava PNG fajljpg -- ucitava JPG fajl

90

Page 91: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Neke osnovne funkcije

Transformacije:

scale factorX factorYrotate angletranslate diffX diffY

Kompozicija:

pictures [ p1, p2, p3, ... ]

91

Page 92: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Osnovna animacija

Ako slika zavisi samo od proteklog vremena, mozemo dakoristimo funkciju animate:

animate :: Display -- prozor-> Color -- boja pozadine-> (Float -> Picture) -- f-ja za iscrtavanje-> IO ()

Funkcija za iscrtavanje prihvata kao argument proteklo vremeod pocetka animacije

92

Page 93: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Simulacija

Ako zelimo da pamtimo neko stanje, i da pravimo simulaciju kodkoje se novo stanje uvek racuna samo na osnovu prethodnog,mozemo da koristimo simulate:

simulate :: Display -- prozor-> Color -- boja pozadine-> Int -- broj slajdova po sekundi-> model -- pocetni model-> (model -> Picture)

-- funkcija prikaza-> (ViewPort -> Float -> model -> model)

-- funkcija azuriranja modela-> IO ()

Funkcija simulate nam daje pristup i velicini prozora.

93

Page 94: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Ulaz sa tastature i misa

Nadogradnja simulacije koja dozvoljava korisnicku obradudogadjaja se zove play

play :: Display -- prozor-> Color -- boja pozadine-> Int -- broj slajdova po sekundi-> world -- pocetni svet-> (world -> Picture)

-- funkcija prikaza-> (Event -> world -> world)

-- funkcija obrade dogadjaja-> [Float -> world -> world]

-- azuriranje modela-> IO ()

94

Page 95: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

CAS 5: HASKELL – FUNKTORI IMONADE

Page 96: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori

class Functor f wherefmap :: (a -> b) -> f a -> f b

96

Page 97: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Liste

class Functor f wherefmap :: (a -> b) -> f a -> f b

instance Functor [] wherefmap = map

97

Page 98: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Maybe

class Functor f wherefmap :: (a -> b) -> f a -> f b

instance Functor Maybe wherefmap f (Just x) = Just (f x)fmap f Nothing = Nothing

98

Page 99: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Maybe

class Functor f wherefmap :: (a -> b) -> f a -> f b

instance Functor Maybe wherefmap f (Just x) = Just (f x)fmap f Nothing = Nothing

99

Page 100: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Primeri

stringToUpper :: String -> StringstringToUpper s = fmap toUpper s

loginName :: Maybe String-- Just jack-- Nothing

name = fmap stringToUpper loginName-- Just JACK-- Nothing

100

Page 101: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Primeri

data Pair = Pair a a deriving (Eq, Show)

instance Functor Pair wherefmap f (Pair a1 a2) = Pair (f a1) (f a2)

fmap (+2) $ Pair 2 3-- Pair 4 5

101

Page 102: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Primeri

data Pair = Pair a a deriving (Eq, Show)

instance Functor Pair wherefmap f (Pair a1 a2) = Pair (f a1) (f a2)

fmap (+2) $ Pair 2 3-- Pair 4 5

102

Page 103: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Either

data Either a b = Left a| Right b

:k Either :: * -> * -> *

Funktor zahteva samo * -> *, pa ne mozemo da napravimoinstancu funktora za Either. Ali mozemo za Either a(karijevanje).

instance Functor (Either e) where-- (a -> b) -> (Either e a) -> (Either e b)fmap f (Left e) = Left efmap f (Right a) = Right (f a)

103

Page 104: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Either

Either ErrorType Int

sqrt' x = if x >= 0 then Right (sqrt x)else Left "Broj je negativan"

104

Page 105: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Either

stringToUpper :: String -> StringstringToUpper s = fmap toUpper s

loginName :: Either String String-- Right jack-- Left "Neka greska"

name = fmap stringToUpper loginName-- Right JACK-- Left "Neka greska"

105

Page 106: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Parovi

Slicno ponasanje je i za parove - funkcija se racuna za drugielement para:

fmap (+4) ("You are number", 2)-- ("You are number", 6)

fmap show ("You are number", 6)-- ("You are number", "6")

Pogledati Bifunctor

106

Page 107: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: IO

instance Functor IO wherefmap f action = do

result <- actionreturn (f result)

Na primer, sledece vraca akciju koja ce vratiti ucitani string sasvim velikim slovima:

fmap toUpperString getLine

main = do lineUpper <- fmap toUpperString getLineputStrLn lineUpper

107

Page 108: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Funkcije (->)

instance Functor ((->) r) wherefmap f g = \x -> f (g x)

Sta ovo znaci?

108

Page 109: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Funkcije (->)

instance Functor ((->) r) wherefmap = (.)

109

Page 110: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Pravila

fmap id = id

fmap (f . g) = fmap f . fmap g

110

Page 111: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Pravila

data CountedMaybe a = CountedNothing| CountedJust Int aderiving Show

instance Functor CountedMaybe wherefmap f CountedNothing

= CountedNothingfmap f (CountedJust counter x)

= CountedJust (counter + 1) (f x)

111

Page 112: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Funktori: Pravila

fmap id (CountedJust 0 "hello")-- CountedJust 1 "hello"

112

Page 113: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Uvod

loginName :: Maybe StringfullNameForLogin :: String -> Maybe String

fmap fullNameForLogin loginName-- Maybe (Maybe String)

113

Page 114: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade

class Monad m wherereturn :: a -> m a(>>=) :: m a -> (a -> m b) -> m b

return a >>= k === k am >>= return === mm >>= (\x -> k x >>= h) === (m >>= k) >>= h

114

Page 115: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Operator bind

Operator (>>=) je ekvivalentan kompoziciji funkcija fmap iflatten (join).

115

Page 116: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Maybe

loginName :: Maybe StringfullNameForLogin :: String -> Maybe String

loginName >>= fullNameForLogin-- Maybe String

116

Page 117: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Maybe

loginName >>= settingsForLogin>>= (setting "desiredDisplayName")>>= ...

-- Maybe a -- ako bilo koja funkcija vrati Nothing,-- rezultat je Nothing

117

Page 118: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Maybe

do login <- loginNamesettings <- settingsForLogindisplayName <- setting "desiredDisplayName"...return result

118

Page 119: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: IO

getLine >>= putStrLn

-- kao:-- join (fmap putStrLn getLine)

119

Page 120: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Operator then

do _ <- getLineputStrLn "Hello world"

getLine >> putStrLn

120

Page 121: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Operator then

do putStrLn "Open the pod doors, HAL."putStrLn "I'm sorry, Dave. I'm afraid I can't..."putStrLn "What's the problem?"putStrLn "I think you know what the problem..."

putStrLn "Open the pod doors, HAL.">> putStrLn "I'm sorry, Dave. I'm afraid I...">> putStrLn "What's the problem?">> putStrLn "I think you know what the problem..."

121

Page 122: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Operator then

do putStrLn "Open the pod doors, HAL."putStrLn "I'm sorry, Dave. I'm afraid I can't..."putStrLn "What's the problem?"putStrLn "I think you know what the problem..."line <- getLineputStrLn line

putStrLn "Open the pod doors, HAL.">> putStrLn "I'm sorry, Dave. I'm afraid I can't...">> putStrLn "What's the problem?">> putStrLn "I think you know what the problem...">> getLine>>= putStrLn

122

Page 123: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade: Funkcije za rad sa monadama

join :: m (m a) -> m amfilter :: (a -> Bool) => m a -> m a

mapM, mapM_forM, forM_

forM args $ \ arg ->radimo nesto sa arg

Videti Control.Monad

123

Page 124: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Monade

Logovanje – vrednost i logFuture – vrednost koja ce biti dostupna u buducnostiLekser – vrednost koja je procitana i ostatak ulaza

. . .

124

Page 125: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

CAS 5: ELM – OSNOVE

Page 126: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Uvod

elm-lang.org

elm-package.json – osnovne informacije o projektuelm-make src/Main.elm --output app/Main.js –kompajlira program

126

Page 127: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Sintaksa

Slicna Haskelu, uz neke izmene:

: umesto :: – tip funkcije ili promenljive:: umesto : – konsturktor liste<< umesto . – kompozicija funkcija<| umesto $ – aplikacija funkcijetype i type alias umesto data i type

127

Page 128: Funkcionalno programiranje - specijalno izdanje, …poincare.matf.bg.ac.rs/~ivan/files/fp/presentation.pdfscala program.scala # pokre´ce program ... set +t # za svaki rezultat ispisuje

Osnovne funkcije programa

main – glavna funkcijainit – inicijalizacija – model i poruka za inicijalizacijuview – funkcija koja deifnise pogled za dati modelupdate – funkcija koja obradjuje poruke i generise novimodel

128