Funkcionálne programovanie

Všetky sú ekvivalentné — Churchova–Turingova téza

$$ {\displaystyle M=\langle Q,\Gamma ,b,\Sigma ,\delta ,q_{0},F\rangle } $$

expression ::= name variable
| expression expression application
| λ name . expression abstraction
| ( expression ) grouping
f af (g b)f a b ≡ (f a) bλa.bλa.f xλa.λb.a ≡ λa.(λb.a)(λa.b) x(λa.λb.a) x y ≡ ((λa.(λb.a)) x) y\a -> b\a -> f x\a -> \b -> a ≡ \a -> (\b -> a)(\a -> b) x(\a -> \b -> a) x y ≡ ((\a -> (\b -> a)) x) yadd :: Int -> Int -> Int
add x y = x + y
-- Je v skutočnosti:
add :: Int -> (Int -> Int)
add = \x -> (\y -> x + y)
λa.a b
a – viazanáb – voľnáλa.(λb.a b c)
a, b – viazané v rámci celej abstrakciea – voľná v rámci λb.a b cc – voľnáλa.a b $\leftrightarrow$ λy.y b(λa.a b) f $\leftrightarrow$ f b(λa.f a) $\leftrightarrow$ fIba pre viazané premenné. Voľné premenné musia zostať voľnými.
(λa.λb.a b) b c $\rightarrow^\beta$ (λb.b b) c — nesprávne
(λa.λb.a b) b c
$\rightarrow^\alpha$ (λa.λx.a x) b c
$\rightarrow^\beta$ (λx.b x) c
$\rightarrow^\beta$ b c
(λa.λb.a b) (λc.c) d
$\rightarrow^\beta$ (λb.(λc.c) b) d
$\rightarrow^\beta$ (λc.c) d
$\rightarrow^\beta$ d
Eta redukcia: (λa.f a) $\leftrightarrow$ f
double x = 2 * x
double = (2 *) -- point-free (eta redukcia)
sum xs = foldl (+) 0 xs
sum = foldl (+) 0 -- point-free
true = λx.λy.xfalse = λx.λy.yifThenElse = λp.λt.λe.p t eifThenElse = λp.pand = λa.λb.a b False = λa.λb.a b aor = λa.λb.a True b = λa.λb.a a bnot = λp.λa.λb.p b aKombinátor — abstrakcia lambda bez voľných premenných.
I = λa.a — funkcia idM = D = λf.f fK = λa.λb.a — funkcia constKI = λa.λb.bC = λf.λa.λb.f b a — funkcia flipK I → (λa.λb.a) (λa.a) → λb.(λa.a) → λa.(λb.b) → KI
true = λx.λy.x = Kfalse = λx.λy.y = KIifThenElse = λp.p = Inot = λp.λa.λb.p b a = Cdata Bool = True | False
not :: Bool -> Bool
not True = False
not False = True
type CBool = forall a. a -> a -> a
cTrue :: CBool
cTrue = \ifTrue ifFalse -> ifTrue
cFalse :: CBool
cFalse = \ifTrue ifFalse -> ifFalse
cNot :: CBool -> CBool
cNot p = p cFalse cTrue
0 = λf.λx.x1 = λf.λx.f x2 = λf.λx.f (f x)3 = λf.λx.f (f (f x))4 = λf.λx.f (f (f (f x)))0 = false
succ = λn.λf.λx.f (n f x)succ 2
$M\equiv$ (λn.λf.λx.f (n f x)) (λf.λx.f (f x))
$\rightarrow^\alpha$ (λn.λf.λx.f (n f x)) (λa.λb.a (a b))
$\rightarrow^\beta$ λf.λx.f ((λa.λb.a (a b)) f x)
$\rightarrow^\beta$ λf.λx.f ((λb.f (f b)) x)
$\rightarrow^\beta$ λf.λx.f (f (f x)) = 3
add = λn.λk.n succ kmult = λn.λk.λf.n (k f)pow = λn.λk.k nB = λf.λg.λa.f (g a) — kompozícia (.)succ = λn.λf. B f (n f)mult = Bpair = λa.λb.λf.f a bfst = λp.p Ksnd = λp.p KItype CPoint = forall r. (Double -> Double -> r) -> r
cPoint :: Double -> Double -> CPoint
cPoint x y = \f -> f x y
movePoint :: CPoint -> Double -> Double -> CPoint
movePoint p dx dy = p (\x y -> cPoint (x + dx) (y + dy))
type CShape = forall r. (CPoint -> Double -> r) -- Circle
-> (CPoint -> CPoint -> r) -- Rectangle
-> r
cCircle :: CPoint -> Double -> CShape
cCircle c r = \fCircle fRectangle -> fCircle c r
cRectangle :: CPoint -> CPoint -> CShape
cRectangle p1 p2 = \fCircle fRectangle -> fRectangle p1 p2
cArea :: CShape -> Double
cArea shape = shape areaCircle areaRectangle
where
areaCircle :: CPoint -> Double -> Double
areaCircle center radius = pi * radius^2
areaRectangle :: CPoint -> CPoint -> Double
areaRectangle p1 p2 =
p1 (\x1 y1 ->
p2 (\x2 y2 -> abs((x2 - x1) * (y2 - y1))))
data List a = Nil | Cons a (List a)
-- Pattern matching:
length :: List a -> Int
length Nil = 0 -- prvá vetva
length (Cons x xs) = 1 + length xs -- druhá vetva
type CList a = forall r. r -> (a -> r -> r) -> r
cNil :: CList a
cNil = \nil cons -> nil
cCons :: a -> CList a -> CList a
cCons x xs = \nil cons -> cons x (xs nil cons)
cLength :: CList a -> Int
cLength list = list 0 (\x rec -> 1 + rec)
fact = λn. (isZero n) 1 (mult n (fact (pred n)))fact v jeho vlastnej definíciifact' = λf.λn. (isZero n) 1 (mult n (f (pred n)))fact = fact' fact – fact je pevný bod funkcie fact'fact = Y fact'Y = (λh.(λx.h (x x)) (λx.h (x x)))
Y g = … = g (Y g)
import Data.Function (fix)
fact = fix (\f n -> if n == 0 then 1 else n * f (n-1))
Všetky funkcie je možné vyjadriť pomocou troch kombinátorov:
S = λf.λg.λa.f a (g a)K = λa.λb.aI = λa.aAlebo dokonca dvoch, lebo I = S K K
λa.a ≡ \a -> aid = \a -> a ≡ id a = aconst = \a -> \b -> a ≡ const a b = a