2016-03-30 7 views
0

Ich versuche, die vorhandene int-Bibliothek zu einer neuen Bibliothek namens "bigint" zu erweitern. Ich halte den Typ des Datentyps bigint als int-Liste. Grundsätzlich möchte ich eine Funktion (lasst es getbigint nennen), die jedes int akzeptiert und jede ihrer Ziffern in einer separaten Zelle der int-Liste speichert und dann diese int-Liste zurückgibt. Also, wenn ich ein:So definieren Sie eine neue Signatur in sml

getbigint 9 

sollte es geben Sie mir:

val it =[9]:bigint 

Wie kann ich das erreichen? Vorläufig nehme ich an, dass die Eingabe für diese Funktion nur eine einzi- ge int ist. Hier ist, was ich bis jetzt getan habe:

signature BigInt = 
    sig 
     type bigint = int list 
     val getbigint: int -> bigint 
    end; 

structure struct_bigint : BigInt = 
    struct 
     fun getbigint (i:int) = 
      let 
       val h = [i]:bigint 
      in h 
      end 
    end 
(*val j = getbigint 9;*) 

was gibt Fehler.

Antwort

1

Eine Signatur implementiert nichts. Es beschreibt, wie eine Struktur nach außen aussieht. Betrachten Sie es als eine Spezifikation. Eine entsprechende Struktur muss Implementierungen der Elemente in der Signatur bereitstellen. Beachten Sie, dass, wenn Sie Ihren Code ausführen Sie folgende Fehlermeldung erhalten:

Error: unmatched type specification: bigint 

SML erkennt, dass Sie etwas in einer Signatur, die nicht durch eine entsprechende Umsetzung in der Struktur angepasst ist.

Ein minimales fix wäre einfach die Linie vor der Umsetzung der fun getbigint

type bigint = int list 

in der Strukturdefinition hinzuzufügen. Dies würde ermöglichen, dass die Linie funktioniert. Aber - es könnte ein bisschen dumm scheint die Linie

type bigint = int list 

zweimal zu haben - einmal in der Signatur und einmal in der Struktur. Und in gewisser Weise ist es ist albern.

Implementierungsdetails gehören nicht wirklich in die Signatur. Es wäre sinnvoller, nur type bigint in der Signatur und die Implementierung in Bezug auf int list in der Struktur zu haben. Dies würde es Ihnen erlauben, später Ihre Meinung über die Implementierung zu ändern (sagen Sie, dass Sie Arrays anstelle von Listen verwenden wollen), so dass Code, der die Struktur verwendet, völlig unberührt ist. Etwas wie:

signature BIGINT = 
    sig 
     type bigint 
     val getbigint: int -> bigint 
    end 

structure BigInt : BIGINT = 
    struct 
     type bigint = int list 

     fun getbigint (i:int): bigint = [i];    
    end; 

reinigte ich Ihre Implementierung von getbigint seit dem let verbindliche in es ein bisschen sinnlos schien, und entschied sich etwas mehr idiomatische für Namen der Signatur (alle Großbuchstaben) und Struktur (Kamel Fall mit führenden Hauptstadt).

Schließlich, beachten Sie, dass getbigint 9 funktioniert nicht aus der Box.Sie können eine von drei Dingen tun:

1) Explizit die qualifizierten Namen verwenden: BigInt.getbigint 9

2) Verwenden Sie die Linie val getbigint = BigInt.getbigint dem Namen getbigint seine beabsichtigte Bedeutung im aktuellen Bereich

3) Verwendung zu geben, die Zeile open BigInt, um die Definitionen der Struktur auf die oberste Ebene zu verschieben. Danach wird getbigint 9 wie erwartet funktionieren.

Als ich mit der Programmierung in SML begann, habe ich viele Strukturen geöffnet (Char, `List etc.). Wenn Sie dies gedankenlos tun, stoßen Sie früher oder später auf Fehler, bei denen das Öffnen einer Struktur zu einem Namenskonflikt führt. Aus diesem Grund verwende ich jetzt fast immer Ansatz 1) oder 2).