F¨ur voneinander abh¨angige Parameter soll jetzt noch die durch lpg inspi-rierte Sprachvariante impliziter formaler Parameter diskutiert werden. Ein impliziter formaler Parameter muss zwar deklariert werden, kann aber in der Parameterliste fehlen, wenn er Teil eines ¨ubergeordneten Parameters ist. Die Struktur Setund zugeh¨orige Instanzannotationen werden dadurch k¨urzer:
structure Set[<]
- weiter wie oben
Allein weil in der Deklaration des <-Parameters der deklarierte Typ α vor-kommt und formale Parameter abgeschlossen sein m¨ussen, wird der Typ α zumimpliziten formalen Parameter. Bei einer Instanziierungset[<0Nat] wird entsprechend der implizite aktuelle Parameter dem Typ des aktuellen Funk-tionsparameters entnommen. Zwar geht dabei offensichtlich redundante In-formation verloren, diese kann man aber bei Bedarf durch Annotationen am ubergeordneten Parameter kompensieren. Statt¨ Set[nat, <] k¨onnte man z.B.
auch Set[<:rel[nat]] schreiben.
Die unannotierte Instanziierung f¨ur Mengen von Mengen set[<[<]] w¨are al-lerdings mehrdeutig. Nur durch set[<[<[ ]] k¨onnte die Mehrdeutigkeit zu Gunsten derunparametrisierten Funktion<0Nataufgel¨ost werden. Geht man auch f¨ur SeqOrd von impliziter Parametrisierung aus, dann w¨urde man die Namen am besten mit ihrer Herkunft annotieren:
set[<0SeqOrd[<0SeqOrd[<0Nat]]]
set[<0Set[<0Set[<0Nat]]]
Das optionale Weglassen untergeordneter Parameter nur bei Instanziierun-gen – also die gemischte Notationset[<[nat, <]] – w¨urde die ¨ Uberlagerungs-aufl¨osung allein an Hand der Anzahl der Parameter erschweren und die Wahr-scheinlichkeit f¨ur Mehrdeutigkeiten erh¨ohen.
Am besten man ¨uberl¨asst es dem Benutzer, sich f¨ur eine feste Anzahl, Rei-henfolge und den Grad der Redundanz durch die formale Parameterliste zu entscheiden! (Denselben Parameter mehrmals anzugeben, ist in Opal ver-boten.) Theoretisch k¨onnte man sogar auf v¨ollig redundanzfreie Parameter bestehen.
Ein Problem der fehlenden Redundanz innerhalb vonSetoffenbart die ¨ Uber-lagerung der <-Funktion f¨ur den Typ set, der ebenso wie α impliziter
Pa-rameter sein k¨onnte. Dabei hilft die Typannotation Set[<: rel[α]] in der formalen Parameterliste. Eine weitere Alternative w¨are obige instanziierte Notation innerhalb von Set:
fun<: set[<]×set[<]→bool
In diesem Fall w¨areoffensichtlich die Funktion <:rel[α] ein Teil der Funkti-on<:rel[set] und der Nameset[<] kann kein Parameter sein, weil formale Parameter unparametrisiert sind.
Gegebenenfalls schließen Definitionsgleichungen Mehrdeutigkeiten mit Para-metern aus (vgl. SeqOrdaus Abschnitt 1.3.1). Weiterhin ist auch die direkte Kennzeichnung formaler Parameter per Position oder Schl¨usselw¨orter vor-stellbar.
Notationell sparsam sind implizite Parameter besonders f¨ur tiefere Abh¨ an-gigkeiten. Dazu betrachten wir die (zu Foo analoge) Struktur SafeSet aus Kapitel 5:
structure SafeSet[proof]
type α
fun <: α×α →bool
import TotalOrder[α, <] only totalOrder
fun proof: totalOrder - Annahme
Die nachfolgende Theorie TotalOrder ist eine Struktur (oder signature) und die Eigenschaft totalOrderist einTypund der Beweis proofeine Kon-stante. F¨ur die Theorie wird auf implizite Parameter verzichtet:
theoryTotalOrder[α, <]
type α
fun <: α×α →bool
law totalOrder - Eigenschaft ist type structure Nat
type nat= . . .
fun <: nat×nat→bool
import TotalOrder only totalOrder
fun Ord: totalOrder[nat, <] - Behauptung
Eine typkorrekte Instanz ist nun SafeSet[Ord]. Mit einer weiteren Dekla-ration Ord: totalOrder[set, <] in SafeSet kann man tiefer geschachtelte Mengen instanziieren: SafeSet[Ord[Ord[Ord0Nat]]].
Der Name Ord steht f¨ur einen Beweis und entspricht einem View aus obj. Der in obj umst¨andliche Morphismus zwischen der formalen Theorie und den aktuellen Parametern aus Nat wird hier elegant durch Parameterlisten gebildet.
Der Beweis, dass die Definition von <0Nat tats¨achlich die in der Theorie ge-forderte Eigenschaft totalOrder erf¨ullt, ist ein anderes Thema. Dem Typ totalOrder fehlt bisher eineDefinition, die besagt, welche Formeln zu erf¨ ul-len sind; totalOrder korrespondiert insofern zu einem Datentyp. Ein kon-kreter Beweis korrespondiert zu einer Definitionsgleichung f¨urOrd. Die Logik und Syntax eines Beweisers umfasst zumindest die konstruktiven Implemen-tierungen (f¨ur natund <) und ist nicht Inhalt dieser Arbeit.
Allein die Behauptung oder Beweisdeklaration Ord soll die statische Sicher-heit vergr¨oßern. Das entspricht der in [DGMP97] diskutierten Erweiterung Opal 2 mit Theorien:
structure Set[α, <]
assume TotalOrder[α, <]
Die Annahme deklariert die formalen Parameter mit ihren Eigenschaften vergleichbar zu lpg. (F¨ur implizite Parameter TotalOrder[<] und Set[<]
w¨are diese Deklarationsform f¨ur eine Benennung vonα ung¨unstig.)
F¨ur die Korrektheit der Instanz Set[nat, <] muss eine entsprechende Be-hauptung TotalOrder[nat, <]existieren, die mit einer Instanzdeklaration aus Haskellvergleichbar ist. InHaskellwird f¨ur den Elementtyp eine Instanz zur Typklasse Ord ben¨otigt, der dann die Implementierung der <-Funktion entnommen wird, um ¨uber Mengen zu operieren.
Die Suche nach einer Instanzdeklaration, bzw. einer geeignet zu instanziie-renden Behauptung, kann durch potenzielle Uberlappungen¨ aber Entscheid-barkeitsprobleme aufwerfen [VS91].
Durch die Parametrisierung in SafeSet wird die ben¨otigte Information, die Implementierung und der Beweis, explizitbenannt und ¨ubergeben. Die impli-ziten Parameter unterst¨utzen lediglich eine k¨urzere Notation langer Parame-terlisten, die nun mit obj und Haskellvergleichbar wird. Wie Datentypen inpvsk¨onnte man auch die TheorieTotalOrderdirekt wie ein Typ betrach-ten:
structure Set[p]
type α
fun <: α×α →bool
assume p: TotalOrder[α, <]
type set
fun <: set×set→bool assert p: TotalOrder[set, <]
- Parameter
- Nicht-Parameter!
Die Schl¨usselw¨orter assume und assertsind als Synonyme f¨urfun zu be-trachten, die sowohl die Unterscheidung von Theorien und echten Typen als auch von Parametern und Nicht-Parametern erm¨oglichen. Ob die m¨ogliche Gleichbezeichnung, also ¨Uberlagerung1 von Strukturen, Funktionen, Typen und/oder Beweisen sinnvoll ist, muss die Praxis zeigen.