Fogások

21.1. Kérdés.
Van egy SML-es kérdésem: egy paraméterként valamilyen struktúrát váró függvénynél hogyan lehet ennek a struktúrának az egyes elemeit elérni?

21.1. Válasz.
Oktató: Nem világos, mit nevez struktúrának. Találgatok:

  1. rekord (record; ezt nevezik a C-ben struktúrának),
  2. ennes (tuple; ez az SML-rekord speciális esete),
  3. struktúra (structure; ez modulfogalom, implementációs modult jelent).
Gondolom, nem az utóbbiról van szó, arról ugyanis a tárgyban keveset tanulunk, és a zárthelyin, a vizsgán, a feladatokban sem igazán kell használni (paraméterként biztosan nem).

Akkor nézzük az első két esetet. Egy függvényben a paramétereket a legkényelmesebb mintaillesztéssel elérhetővé tenni. Ha a paraméter összetett, akkor használhatunk

  1. összetett mintát (általában ez az ajánlott, olvashatóbb megoldás),
  2. (kiválasztó) függvényt.
Példák összetett mintára:

  1. rekordminta

    fun // {den = 0, ...}     = raise Domain
      | // {num = n, den = d} = (real n) / (real d);
    vagy

    fun // {den = 0, ...} = raise Domain
      | // {num, den}     = (real num) / (real den);

  2. ennesminta

    fun iterlen ([], n) = n
      | iterlen (_::xs, n) = iterlen(xs, n+1);

Példák kiválasztófüggvény alkalmazására:

  1. ha rekord a paraméter:

    type rat = {num : int, den : int};
    fun // (r : rat) = if #den r = 0
                       then raise Domain
                       else real(#num r)/real(#den r);

  2. ha ennes a paraméter:

    fun iterlen p = if null(#1 p)
                    then #2 p
                    else iterlen(tl(#1 p), #2 p + 1);

A kérdező folytatja: Konkrétan az is érdekel, hogy ha a struktúrának valamelyik eleme lista, az ilyen elemet hogyan lehet elérni. Ugyanúgy, mint általában, vagy másképp? Tud estetleg mutatni valaki ezekre egy-egy rövid programrészletet?

Oktató: Ugyanúgy, lásd a fenti példákat: mind az x::xs jellegű minta, mind a hd, tl, null stb. függvények használhatók. Általában javasolom a mintaillesztést. Természetesen lista lehet ennes, rekord vagy más lista eleme is.

21.2. Kérdés.
Hogy lehet SML-ben egy számról eldönteni, hogy páros-e vagy páratlan? Van erre valami beépített függvény?

21.2. Válasz.
Oktató: Beépített függvény nincs. De pl. könnyen megoldható a feladat az fn x => x mod 2 = 0 lambda-függvénnyel.

21.3. Kérdés.
Olyan problémába ütköztem, hogy van 2 függvényem, és egymást akarják meghívni, de az sml az elsőnél hibát ír jelez, mert ott még nincs deklarálva a második.

21.3. Válasz.
Oktató: Kölcsönösen rekurzív függvényeket az and kulcsszóval elválasztva lehet definiálni. Példa:

fun even x = ...
and odd  x = ...
Lásd még a jegyzetben az Egyidejű deklaráció c. szakaszt, valamint a jelen GYIK más fejezeteit.


Deklaratív programozás - FP-GYIK
2005. március 1.