Függvényhasználat, mintaillesztés, kiértékelés
Függvényhasználat, kötési erősség
A függvényeket lehet prefix
és infix
módon használni.
Infix módon a két paraméteres függvényeket lehet használi.
A kötési erősség határozza meg hogy melyik függvény fog először végrehajtódni pl.: +
vagy *
.
Prefix
A függvény neve elöl áll pl.: f 2 3
Prefix módon használt függvények kötési erőssége 10
tehát 1 + f 2 3 esetben nem kell zárójelezni mert az f erősebb mint a +.
f :: Int -> Int -> Int
f a b = a + b
-- f 2 3 -- 5
Infix
A függvény neve középen áll pl.: 2 `f` 3 és a fügvényt `` karakterek közé kell tenni.
Ilyenkor kétféle kötést különböztetünk meg infixr
és infixl
.
Ha a függvényünk infixr
akkor jobbra zárójelez, ha infixl
akkor balra.
f :: Int -> Int -> Int
f a b = a + b
infixr 5 `f` -- így adható meg az általunk definiált függvény infix kötése
Infix függvények használata perfixként?
Ha a függvény nevét zárójelek közé tesszük akkor perfixként is használhatjuk.
(+) 5 6
(*) 2 3
Mintaillesztés
A mintaillesztés segítségével tudjuk a függvényeket több esetre bontani, olyan mintákat irhatunk le amire az adott típus illeszkedni tud:
numbers :: Int -> Int
numbers 1 = 2
numbers 2 = 4
isTrue :: Bool -> Bool
isTrue True = True
isTrue False = False
isBchar :: Char -> Bool
isBchar 'b' = True
isBchar 'B' = True
A mintákon lineárisan, egymás után halad végig és figyeli hogy illeszkedik-e rá a paraméter.
A fenti példában az isTrue
függvény totális, a numbers
és isBChar
is parciális függvények.
Ha a numbers
függvénynek paraméterül adunk egy 3
-at akkor a futási hibát kapunk, ugyanis nem deklaráltuk hogy a 3
-mal mit csináljon a numbers
függvény.
Az isTrue
függvénynek bármilyen Bool
típusú paramétert adhatunk, mivel minden Bool
típusú paraméterre definiált.
"Joker" minta, elnevezett minta
Ha _ teszünk a minta helyére akkor az azt jelenti, hogy az értékét nem használjuk fel, ezért ez bármilyen típusra illeszkedni fog.
Egyéb esetben akármilyen névvel elnevezhetjük a mintát, amennyiben az nem létező függvény, kulcsszó vagy korábban használt elnevezés.
numbers :: Int -> Int
numbers 1 = 2
numbers 2 = 4
numbers valamilyenszam = valamilyenszam
-- így a függvény már totális
isTrue :: Bool -> Bool
isTrue ertek = ertek
-- fölösleges mintát illeszteni, ha ugyan azt az értéket adjuk vissza
isBchar :: Char -> Bool
isBchar 'b' = True
isBchar 'B' = True
isBchar _ = False
-- így a függvény már totális
addNumbers :: Int -> Int -> Int
addNumbers a a = a + a --hibás definició
Infix definícióban
Függvény definiálásakor is lehet használni az infix formáját.
f :: Integer -> Integer -> Integer
a `f` b = a + b
infixr 5 `f`
Kiértékelés
A Haskell lusta nyelv, ha nem muszáj nem számol.
threeBool :: Bool -> Bool -> Bool -> Bool
threeBool a b c = a && b && c
ha a függvénynek adunk egy False értéket akkor a függvény nem fogja kiértékelni a többi paramétert, mivel a && operátor bal oldali paramétere False, így a függvény visszatérési értéke is False lesz
Ez az && fügvény lustán történő definiálása miatt van:
(&&) :: Bool -> Bool -> Bool
(&&) True b = b
(&&) False _ = False
ez azt is fogja jelenteni, ha a fügvénynek valamilyen futási hibát okozó értéket adnánk át akkor az se fog kiértékelődni
- pl.: threeBool False True (2 `div` 0) -> False
constTrue :: Bool -> Bool
constTrue _ = True
constFalse :: Bool -> Bool
constFalse érték = False
a lustaság ugyanúgy vonatkozik a mintaillesztésre is, ha nincs felhasználva az = jobb oldalán akkor nem fogja kiértékelni
- pl.: constTrue (4 `div` 0) -> True
- pl.: constFalse (10 `div` 0) -> False