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