2012-03-28 5 views
0

ich eine Funktion für einen neuen Datentyp in Standard ML machen will, der Datentyp intnest genannt wird, definiert als die folgenden:Standard ml hinzufügen, Elemente in einem benutzerdefinierten Datentyp

datatype intnest = 
    INT of int 
| LIST of intnest list; 

und ich möchte eine Funktion machen dass alle Zahlen in der intlist fügt hinzu, habe ich versucht, den folgenden Code:

fun addup (INT n) = n 
    | addup (LIST x::xs) = x + addup(xs); 

Was mache ich falsch?

EDIT:

Ich habe auch versucht die folgenden:

fun addup (INT n) = n 
    | addup (LIST x::xs) = addup(x) + addup(xs); 

so dass x vom Typ INT ist so die erste Option, die int-Wert zurückgibt und die addup (xs) ist eine rekursive Aufruf zurückkehren die gleiche zweite Option.

auch versucht, die folgenden:

fun addup (INT n) = n 
    | addup (LIST []) = 0 
    | addup (LIST x::xs) = addup(x) + addup(LIST xs); 

aber ich bekomme die folgende Fehlermeldung:

stdIn:146.4-151.50 Error: parameter or result constraints of clauses don't agree [tycon mismatch] 
    this clause:  intnest list -> 'Z 
    previous clauses:  intnest -> 'Z 
    in declaration: 
    addup = 
     (fn INT n => n 
     | LIST nil => 0 
     | :: (<pat>,<pat>) => addup <exp> + addup <exp>) 
stdIn:151.25-151.50 Error: operator and operand don't agree [tycon mismatch] 
    operator domain: intnest 
    operand:   intnest list 
    in expression: 
    addup x 

Antwort

0

Erstens gibt es einen Syntaxfehler in der LIST Fall; befreie die of. Sie möchten, dass der Fall wie addup (LIST(x::xs)) = ... aussieht.

Konkreter gibt es konzeptionelle Probleme in addup. Der gewünschte Typ von addup scheint intnest -> int zu sein. Es muss daher sichergestellt werden, dass addup immer auf intnest Werte angewendet wird und int Werte zurückgegeben werden.

Betrachten Sie nun den Typ der Elemente der Liste x::xs. Sie definierten es als LIST of intnest list, also x ist ein intnest. Aber in addup behandeln Sie x als eine ganze Zahl.

In die gleiche Richtung, ist xs ein intnest list, aber das ist nicht ein intnest, das ist, was Sie es wie in addup(xs) sind zu behandeln. Ihre überarbeitete Version behebt das Problem mit x, aber nicht das mit xs. Sie müssen einen intnest von xs mit LIST machen, was bedeutet, dass Sie addup(LIST xs) verwenden müssen.

Schließlich fehlt Ihnen ein Fall. Was passiert, wenn Sie LIST [] haben?

Die dritte Version funktioniert nicht, weil Sie benötigte Klammern vermissen. Der Compiler teilt Ihnen mit, dass Sie einen intnest list als einen der Fälle verwenden (den :: Fall). Das heißt, es sieht LIST x::xs als (LIST x) :: xs.

+0

Ich habe dich nicht ganz verstanden, ist nicht xs eine Liste von innersten? –

+0

@ aizen92 Ja, genau das ist es. Aber der Typ, den du für 'addup' brauchst, ist' innerest'. Ihr 'LIST'-Fall wird * unter Verwendung einer 'innersten Liste' implementiert, ist aber * nicht * eine 'innerste Liste'. Es könnte helfen, die Typen von 'xs' und' LIST xs' zu vergleichen. –

+0

Das Problem war mit den Klammern zwischen x :: xs, aber ich verstehe nicht ganz, warum das ist, wird nicht x :: xs als ein Objekt betrachtet, das ist eine Liste? –