Kihagyás

2. előadás - Mintaillesztés

Függvény alapinformációk

1.0 / 2.0

1 `div` 2

/ Törtszámokat tud kezelni, míg a div csak egészeket

1 `div` 2  --> egészszámot tud kezelni 

Backtick függvényhívásra

1 `div` 2
{--eredeti függvény--} div 1 2 --> A backtick miatt két paraméter közé kerülhet

Backtick-es Függvény hívása több paraméterre

(1 `f` 2) 3 

Működik, mert a függvény egy nem teljes függvényt ad vissza, tehát kell még egy operátor (viszont így csak egy paraméter kerülhet balra)

Műveleti sorrend

(+) 2 3

Fontos: Az operátorok meghívhatóak függvényként, ha zárójelek közé írjuk

Operátor precedencia és az infix leírás

Infix leírás a csoportosítás nélküli leírás, ilyenkor a műveleti sorrendre hagyatkozunk (mint egy képletben)

Műveleti sorrend megvalósítása

GHCI-ben :i <kifejezés> le tudja kérni az adott kifejezés információit

infixl 7 * -> Infix használatnál balra köt 7-es erősséggel (nagyobb erősebb, a (+) erőssége kevesebb, mint (*))

függvényhívás mindennél magasabb renddű (10)

Syntactic sugar, avagy függvény szinonímák

Legjobb példa a negate függvény, ami a negatív szám fogalmát teszi lehetővé, azonban a fordító ezt a - jelre cseréli (Fontos, ez nem egyenlő az előjellel más nyelveknél, mert itt nem így működik!)

7 + -6     --> HIBÁS, mert a `-` egy függvény (negate)
7 + (-6)   --> , mert előbb történik meg az előjel váltás
7 - 6      --> , mert két argumentummal a `-` a kivonás függvény

Mintaillesztés

Totális függvények

Azon függvények, amik minden lehetséges bemenetre megoldással szolgálnak

f :: Int -> Int
f 0 = 10
f x = x + 1
f y = y + 2     --> Ezt nem látná, mert az első minta illesztése egyezik (visszatér x+1-gyel)

Parciális függvények

Azon függvények, amik nem minden esetben szolgálnak eredménnyel, potenciális hibalehetőséggel (a szándékosan hibát dobó függvények is parciálisnak minősülnek, hiszen a Haskell-nem nincs hibakezelés)

g :: Int -> Int --> Itt a minden lehetséges bemenet a rövid egészek (Int)
g 0 = 10        --> Csak a 10 esetében , a többi minta nem lett illesztve

Minták mintaillesztésre

neg :: Bool -> Bool
neg True = False
neg False = True

(&&&) :: Bool -> Bool -> Bool
True &&& True = True
x &&& y = False

(&&&&) :: Bool -> Bool -> Bool
True &&&& True = True
_ &&&& _ = False --> Anonimus változó, mert nem kell az értéke

Az anonimus operátor sok nyelvhez hasonlóan itt is a _, használata akkor ajánlott, amikor egy adott mintánál valamely bemenet értéke nem szükséges a minta illesztéséhez.


Lusta kiértékelés fontossága

Bizonyos feltételeket előbb is meg tudunk határozni, mint hogy minden bemeneti állapotot ellenőrzünk, ilyenkor fontos, hogy melyik operandust vizsgáljuk elsőként

A rendszerben deffiniált függvények alapértelmezett illesztése balra történik.

(&&&&&) :: Bool -> Bool -> Bool  --> Balról illeszt (az első paraméter van figyelve, a másodikat csak akkor nézi, ha kell)
False &&&&& _ = False
True &&&&& x = x

(&&&&&&) :: Bool -> Bool -> Bool --> Jobbról illeszt (a második paraméterrel csinálja ugyanazt, mint az előző)
_ &&&&&& False = False
x &&&&&& True = x

(|||) :: Bool -> Bool -> Bool
True ||| _ = True
_ ||| x = x

Rendezett pár (,)

Előre deffiniált függvényei az fst és a snd, ami rendre az első és a második tagját adják vissza a párosnak.

Rendezett listák egészen 64 elemig deffiniálva vannak, azonban azok 'getterjei' nincsenek megadva, azokat amennyiben szükség lenne rá, külön kell deffiniálni!

a :: (Int, Int)
a = (1, 2)

mirror :: (Int, Int) -> (Int, Int)
mirror x = (fst x, negate (snd x))

mirror' :: (Int, Int) -> (Int, Int)
mirror' (x, y) = (x, negate y)

h :: (Int, Int) -> (Int, Int)
h (0, 0) = (10, 10)
h (x, y) = (x + 1, y + 1)


mirrorXZ :: (Int, Int, Int) -> (Int, Int, Int)
mirrorXZ (x,y,z) = (x, negate y, z)