Az Euclid programozási nyelv

Sablonok:paraméterezett típusok

A paraméterezett típusokat az Adához hasonlóan lehet használni. Pl.: (felhasználó definiálta String típus)

type String (maxLen: unsignedInt) = record var chars: array 1 .. maxLen of char var length: 0 .. maxLen := 0 end String ... var name: String (50) var address: String (100)


A típus egy paraméterére úgy hivatkozhatunk, mint egy rekord-komponensre, pl. name.maxLen. A beépített típuskonstruktorok is kaphatnak paramétereket. Formálisan : type T(fp1 : T1,...,fpn : Tn) = ... ahol fp1,...,fpn a fomális paraméterek listája. Az egy típusra vonatkozó formális paramétereknek konstansnak kell lenniük, és csak elérhető, formális paramétert nem tartalmazó típusra hivatkozhatnak. Ha egy eljárás formális paraméterlistája egy paraméteres típusra hivatkozik, a hivatkozás aktuális paramétere lehet az eljárás korábbi formális paramétere. Minden paraméterezett típusra való hivatkozás csak akkor szabályos, ha az összes formális paramétert helyettesítjük aktuális paraméterrel. Ha tehát megadjuk az aktuális paramétereket, akkor azok értékeit is rögzítettük, és ezzel egy paraméterezetlen típust kapunk.
Lehetőság van azonban arra, hogy a paraméterek értékének rögzítését késleltessük. Van két speciális aktuális paraméter, az any és az unknown, amelyekkel ez elérhető.
Tegyük fel, hogy van egy paraméterezett típusunk, ez a V, van egy formális paramétere, az s, ami T tipusu ( T felsorolás típus ). Röviden : V(s:T). Ha most azt írjuk, hogy V(any), akkor ez azt a típust jelöli, amely a V(s1),...,V(sn) típusok uniójával egyezik meg ( s1,...,sn a felsorolás típus értékei ). Így tehát egy x : V(any) változódefiniálás esetén nem adtuk meg előre, hogy az x mely konkrét V(si) típus eleme lesz. Ha egy y : V(si) változót definiálunk, akkor x:=y értékadás helyes, de fordítva nem. Ha a V egy rekord tipus, aminek case-szerkezetű törzse van (azaz variáns rekord, s:T a variáns rekord diszkriminánsa), akkor az x s paramétere változhat futásidőben.
Tegyük fel, hogy van egy collection of T(...,unknown,...) típusunk. Ez azt jelenti, hogy nem adjuk meg előre, hogy mi a collection alaptípusa, hanem majd csak akkor adunk "igazi" értéket az unknown helyére, amikor definiálunk v. deklarálunk egy v : T(...,x,...) változót, ahol az x már egy konkrét érték. Tehát egészen a helyfoglalásig késleltettük a konkrét értékmeghatározást.
Például:

type FamilyMember (sex : SexType) = forward var members : collection of FamilyMember(unknown) type FamilyMember = record var age :0..100 var mother, father : ^members var oldestChild : ^members end FamilyMember type Subject = FamilyMember(any) type Family = ^members


Az első sorban deklaráljuk a FamilyMember típust ( azért forward, mert később kerül kifejtésre ). Ezután lesz egy members nevű változónk, ami ilyen előre nem definiált FamilyMemberek halmaza. Ezután már meg tudjuk adni a FamilyMember típust. A mother, father, oldestChild változók mutatók a members változóra. Ezért ha most meg akarunk adni konkrét értékeket, akkor pl. az var x : FamilyMember(male) definíció jó lesz. A SexType típus is felsorolás típus, male, female elemekkel.
Ha a T egy rutin egy formális paraméterének a típusa, akkor a T egy vagy több paraméterét parameter-ként is megadhatjuk, ezzel azt jelöljük, hogy ezek további paraméterek (amik majd jönnek az aktuális paraméterrel együtt).
Íme egy másik példa:

type DataArraySegment(m, n: 1..256) = array m..n of signedInt {az 'a' param. tipusanak deklaracioja} ... function FindMax ( a :DataArraySegment(parameter, parameter) ) returns index : signedInt = post { k in a.m .. a.n -> a(index)>=a(k) } begin index := a.m for i in a.m+1 .. a.n loop assert { k in a.m .. i-1 -> a(index)>= a(k) } if a(i) > a(index) then index := i end if end loop end FindMax {majd egy kesobbi hivas:} begin ... ... var aa : DataArraySegment(5,24) ...... var maxIndex : signedInt = FindMax(aa)