Frage

Ist es möglich, Funktionen mit dynamisch typisierten Eingabeparametern zu schreiben? Ich habe versucht, Pattern-Matching, aber anscheinend ist es nicht wie das funktioniert.

Ich möchte etwas tun:

fun firstStr (0,n:string) = n
  | firstStr (b:string,n:string) = if b>n then n else b;

Danke.

War es hilfreich?

Lösung

StandardML ist eine strenge, statisch typisierte Sprache. Daher können Sie nicht eine Funktion haben, die in der zweiten einen int im ersten Fall und einen String akzeptiert. Der Fehler, den Sie erhalten, ist

this clause:        string * string -> 'Z
previous clauses:      int * string -> 'Z
in declaration:
  firstStr =
    (fn (0,<pat> : string) => n
      | (<pat> : string,<pat> : string) => if <exp> > <exp> then n else b)

Wenn Sie einen Fall haben wollen, die eine Zeichenfolge und ein Fall ist, die ein int ist, können Sie eine neue Art zu machen, ein „ getaggt Vereinigung “(auch bekannt als‚diskriminierte Union‘), die leicht gestaltet ist mit Mustervergleich zu verwenden. Es würde wie folgt aussehen:

datatype Wrapper = Int    of int
                 | String of string
fun firstStr(Int 0,    n:string) = n
  | firstStr(String b, n:string) = if b>n then n else b

Natürlich mögen Sie vielleicht etwas passenderen Namen für diesen Wrapper-Typen zu finden, etwas, den Sinn im Rahmen des Programms macht. Bitte beachten Sie auch, dass die Art Anmerkung auf n ist nicht wirklich notwendig; es würde mehr idiomatische schreiben

fun firstStr(Int 0,    n) = n
  | firstStr(String b, n) = if b>n then n else b

Darüber hinaus wird der Compiler Ihnen sagen, Sie verlassen haben einen Fall aufgedeckt:? Was ist, wenn das erste Argument eine ganze Zahl nicht gleich Null

Schließlich ist es nicht wirklich klar, was man durch den Vergleich b>n bedeuten, was Aspekt der beiden Strings wollen Sie vergleichen? Ich sehe, dass, wenn ich zwei Strings in SML vergleichen, ich sehe einen lexikographischen (aka alphabetisch) Vergleich. Ist das, was Sie wollen?

Andere Tipps

Um ein wenig zu erarbeiten: Angenommen, Sie zwei Argumente haben, von denen jede eine Zeichenfolge oder eine ganze Zahl sein könnte, und wenn Sie zwei Strings haben möchten Sie die lexikographisch kleinere Zeichenfolge, wenn Sie eine Zeichenfolge haben wollen Sie diese Zeichenfolge, und wenn Sie zwei ganzen Zahlen haben, können Sie nicht einen String zurück. Wie geht's? Gibt einen Wert vom Typ string option (aufblicken option, SOME und NONE unter http: //www.standardml .org / Basis / option.html ):

datatype string_or_int = String of string
                       | Int    of int 

fun firstStr(String a, String b) = SOME (if a < b then a else b)
  | firstStr(String a, Int _   ) = SOME a
  | firstStr(Int _,    String b) = SOME b
  | firstStr(Int _,    Int _   ) = NONE

Funktion firstStr hat Typ

string_or_int * string_or_int -> string option

Der schnellste Weg, ein geübter ML Programmierer zu werden ist zu lernen Typen zuerst denken . Wenn zum Beispiel, was Sie wirklich wollte, war eine Funktion vom Typ string option * string -> string, würden Sie es nicht selbst schreiben müssen; die eingebaute Funktion getOpt das tut. Auf der anderen Seite, es klingt wie Sie string option * string -> string wollen, so können Sie schreiben

fun firstStr(SOME a, b) = if a < b then a else b
  | firstStr(NONE,   b) = b

und Sie nicht einen SOME Wert Konstruktor oder einen option Typen auf dem Ergebnis‘müssen.

polymorphe Varianten in OCaml haben mehr die dynamische Eigenschaft, die Sie suchen. Sie können einen Blick, wenn Sie wollen, OCaml und SML sind ganz in der Nähe Sprachen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top