Többsoros függvénydefiníciók

Lokális definíciók

Példa:

res = f * (f - y)  where
 
    y = 1 / 4
 
    f = 6 * y

Szintaxis:

Szemantika: Korlátozott látókör a változók (y, f) számára.


A lokális definíciók korlátozott látókörű konstans és függvénydefiníciók.

A lokális definíciók szintaktikája:

A res globális definíció, azaz a modulban mindenütt látható. Az f és y lokális definíciók, ezek csak egymás számára láthatóak, továbbá láthatóak a where előtti definícióban.

A where kulcsszót érdemes a sor végére tenni. A where írható a következő sorba is, de mindenképp beljebb kell húzni, mint az azt megelőző definíciót.

Lokális definíciót akkor érdemes használni, ha egyidejűleg teljesül a következő két kitétel:

Példa

A függvénykompozíció definiálása lokális definícióval:

(.) :: (b -> c) -> (a -> b) -> (a -> c)

f . g = h  where

  h x = f (g x)

A függvénykompozíció definiálása lokális definíció nélkül:

(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

Konstans minták

Konstans definiálásakor a konstans neve helyett írhatunk tetszőleges mintát:

[one,two,three,four,five] = [1..5]

Ezzel öt konstanst definiáltunk:

Test>
1 :: Integer
Test>
2 :: Integer
Test>
3 :: Integer
Test>
4 :: Integer
Test>
5 :: Integer

Alkalmazás

A konstans minták hasznosak, ha egy n-est visszaadó függvény végeredményére akarunk mintát illeszteni. Példa:

unzip :: [(a, b)] -> ([a], [b])

Test>
([1, 3, 4], "xzv") :: ([Integer], [Char])

Feladat: Prelude.splitAt [*]

Definiáljuk újra a splitAt függvényt! Készítsünk a következőnél hatékonyabb definíciót:

-- splitAt n l = (take n l, drop n l)
splitAt :: Int -> [a] -> ([a], [a])

Test>
([1, 2, 3], [4, 5, 6, 7, 8, 9]) :: ([Integer], [Integer])
Test>
([], [1, 2, 3, 4, 5, 6, 7, 8, 9]) :: ([Integer], [Integer])
Test>
([1, 2, 3, 4, 5, 6, 7, 8, 9], []) :: ([Integer], [Integer])

Feladat: Lista kettéosztása

split :: [a] -> ([a], [a])

Test>
([1, 3, 5, 7], [2, 4, 6, 8]) :: ([Integer], [Integer])
Test>
([1, 3, 5, 7, 9], [2, 4, 6, 8]) :: ([Integer], [Integer])

Feladat: Összefésüléses rendezés [*]

Definiáljuk az összefésüléses rendezést! A egynél több elemű listákat osszunk ketté (split), majd rendezés után fésüljük össze a két részt (az esetszétválasztás sortMerge függvénye).

msort :: Ord a => [a] -> [a]

Test>
[0, 1, 2, 3, 4, 6, 11] :: [Integer]
Test>
[1, 1, 2, 2] :: [Integer]