DVOP PIT
Bc. Matěj Cajthaml — SSPŠ
© 2025
Existují modernější funkcionální jazyky, např.: Haskell, Erlang, F#
Funkce jsou ale všude — lze aplikovat i v jiných jazycích. Viz např. JavaScript, LINQ v C#, ...
#lang racket
racket
spustí překlad a interpretacidefine
#lang racket
; (define (jmenoFunkce parametry...)
; teloFunkce)
(define (add x y)
(+ x y))
Racket a další jazyky mají předpřipravené operátory. Např.: (+ 1 2)
je ekvivalentní
zápisu
1 + 2
v jiných jazycích.
Vyhodnoďte následující výrazy:
(/ 1 2)
(floor (/ 1 2))
(+ 1 (* 2 3))
(+ 1 (* 2 (- 3 4)))
(+ (ceiling (/ 1 2)) (* 2 (3 (- 4 5))))
#t
#f
(not x)
(and x y)
(or x y)
(= x y)
(< x y)
(> x y)
(<= x y)
(>= x y)
(+ x y)
(- x y)
(* x y)
(/ x y)
(floor x)
(ceiling x)
(print x)
(newline)
Vyhodnoďte následující výrazy:
(not #t)
(and #t #f)
(or (not #t) #f)
(= 1 (+ 1 (* 2 3)))
(< 1 (+ 1 (* 2 3)))
(> 1 (+ 1 (* 2 3)))
#lang racket
(define (add x y)
(+ x y))
(add 1 2)
(add (add 1 2) 3)
(if test then else)
#t
, vyhodnotí se then
#f
, vyhodnotí se else
#lang racket
(define (abs x)
(if (< x 0)
(- x)
x))
V racketu neexistuje jednoduchá iterace — většinu věcí řešíme pomocí rekurze a různých funkcí.
#lang racket
(define (factorial n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
Napište následující funkce:
(inc x)
— zvýší číslo o 1(dec x)
— sníží číslo o 1(zero? x)
— zjistí, zda je číslo 0(add x y)
— sečte dvě čísla pomocí funkcí výše(mul x y)
— vynásobí dvě čísla pomocí funkce
add
Napište program, který vypočítá mocninu čísla x
s exponentem n
.
Napište program, který vypočítá n
-tý prvek Fibonacciho posloupnosti.
(a . b)
empty
(1 2 3)
je reprezentován jako (1 . (2 . (3 .
empty)))
(cons a b)
— vytvoří buňku (a . b)
(car x)
— vrátí hlavu buňky(cdr x)
— vrátí zbytek buňky(list a b c)
— vytvoří list (a b c)
(null? x)
— zjistí, zda je list prázdný(equal? x y)
#t
, pokud jsou x
a y
stejné
(včetně
struktury)
#f
#lang racket
(define (sum list)
(if (null? list)
0
(+ (car list) (sum (cdr list)))))
(sum '(1 2 3 4 5 6 7 8 9 10))
(define (second list)
(car (cdr list)))
(second '(1 2 3 4 5 6 7 8 9 10))
(second '(1))
(define (makeList n)
(if (= n 0)
'()
(cons n (makeList (- n 1)))))
'
či (quote x)
— zamezí evaluaciNapište vlastní funkci length
, která spočítá délku listu.
Napište funkci (nth n list)
, která vrátí n
-tý prvek listu.
Napište funkce (min list)
a (max list)
, které vrátí nejmenší a
největší prvek listu.
Napište funkci (contains? list x)
, která zjistí, zda list obsahuje prvek
x
.
Napište funkci (range a b)
, která vytvoří list čísel od a
do
b
.
Napište funkci (reverse list)
, která prohodí prvky listu (první s posledním,
druhý s předposledním, atd.).
Napište funkci (remove list x)
, která odstraní všechny výskyty prvku
x
z listu.
Napište program, který zjistí, zda zadané číslo je prvočíslo.
Prvočíslo je číslo, které je dělitelné pouze jedničkou a sebou samým.
Co když potřebujeme ve funkci několikrát použít stejný výraz?
(let (variables) body)
(name value)
#lang racket
(define (f x)
(let ([y (+ x 1)])
(+ (* x y) y)))
if
(cond (test1 body1) (test2 body2) ...)
else
#lang racket
(define (fib n)
(cond
[(= n 0) 0]
[(= n 1) 1]
[else (+ (fib (- n 1)) (fib (- n 2)))]))
Rekurze jsou pomalé. Proč?
#lang racket
; recursion normal
(define (factorial n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
(factorial 5)
; recursion tail recursive
(define (factorialTail n)
(factorialTailInner n 1))
(define (factorialTailInner n acc)
(if (= n 0)
acc
(factorialTailInner (- n 1) (* n acc))))
(factorialTail 5)
Můžeme definovat funkci uvnitř funkce?
map
, filter
, fold
(lambda (params) body)
#lang racket
; calculate damage for entity type
(define (damage calc type)
(calc type))
(damage
(lambda (type)
(cond
[(eq? type 'fire) 10]
[(eq? type 'water) 5]
[(eq? type 'grass) 15]
[else 0]))
'fire)
Aplikuje funkci na každý prvek seznamu a vrátí seznam výsledků.
#lang racket
(map (lambda (x) (* x x))
'(1 2 3 4 5))
Vrátí seznam prvků, které splňují podmínku.
#lang racket
(filter (lambda (x) (not (zero? x))) '(1 2 0 3 0 4 5 0 6 0 7))
Prochází seznam a vrací jednu hodnotu. Foldr prochází seznam zprava doleva, foldl zleva doprava.
#lang racket
(foldr (lambda (x y) (+ x y)) 0 '(1 2 3 4 5))
(foldr (lambda (x y) (cons x y)) '() '(1 2 3 4 5))
(foldr (lambda (x y) (cond [(even? x) (cons x y)] [else y])) '() '(1 2 3 4 5))
(foldr (lambda (x y) (ceiling (/ x y))) 1 '(1 2 3 4 5))
(foldl (lambda (x y) (ceiling (/ x y))) 1 '(1 2 3 4 5))
Co se stane, když ve funkci budeme po sobě volat více funkcí?
#lang racket
(define (example x)
(+ x 1)
(- x 10))
(example 5)
Vytvořte vlastní implementace funkcí map
, filter
a foldr
. Nepoužívejte vestavěné funkce.
Vytvořte funkci, která vytvoří seznam prvočísel menších než zadané číslo pomocí Eratosthenova síta. Použijte funkcí filter
.