12 Stimmen

Wie entscheidet Ocaml die Reihenfolge für benutzerdefinierte Operatoren?

Ich möchte nette Operatoren für komplexe Arithmetik haben, um meinen Code übersichtlicher zu gestalten. Ocaml hat ein Complex-Modul, daher möchte ich einfach Operatoren hinzufügen, die diese Funktionen aufrufen.

Der intuitivste Weg für mich ist es, einen neuen komplexen Operator aus allen üblichen Operatoren zu erstellen, indem ich '&' an das Operator-Symbol anhänge. So werden +& und *& komplexe Addition und Multiplikation sein. Ich möchte auch ~& als komplexe Konjugation haben.

Wenn ich diese Operatoren verwenden werde, möchte ich, dass sie sich genauso wie normale Arithmetik verbinden. Basierend auf den folgenden Sitzungen, verhalten sie sich automatisch so, wie ich möchte, aber ich würde gerne verstehen, warum, damit ich keine schrecklichen Fehler bekomme, wenn ich weitere Operatoren einführe.

Meine derzeitige Vermutung ist, dass ihre Präzedenz durch das lexikalische Sortieren der Operator-Symbole gemäß einer Ordnung erfolgt, die mit der Präzedenz der normalen Arithmetik konsistent ist. Aber ich kann das nicht bestätigen.

Sitzung eins:

# open Complex;;
# let (+&) a b = add a b;;
val ( +& ) : Complex.t -> Complex.t -> Complex.t = 
# let ( *&) a b = mul a b;;
val ( *& ) : Complex.t -> Complex.t -> Complex.t = 
# one +& zero *& one +& zero *& one;;
- : Complex.t = {re = 1.; im = 0.}
# zero +& one *& zero +& one *& zero;;
- : Complex.t = {re = 0.; im = 0.}
# i +& i *& i +& i *& i *& i;;
- : Complex.t = {re = -1.; im = 0.}

Sitzung zwei:

# open Complex;;
# let ( *&) a b = mul a b;;
val ( *& ) : Complex.t -> Complex.t -> Complex.t = 
# let (+&) a b = add a b;;
val ( +& ) : Complex.t -> Complex.t -> Complex.t = 
# one +& zero *& one +& zero *& one;;
- : Complex.t = {re = 1.; im = 0.}
# zero +& one *& zero +& one *& zero;;
- : Complex.t = {re = 0.; im = 0.}
# i +& i *& i +& i *& i *& i;;
- : Complex.t = {re = -1.; im = 0.}
# let (~&) a = conj a;;
val ( ~& ) : Complex.t -> Complex.t = 
# (one +& i) *& ~& (one +& i);;
- : Complex.t = {re = 2.; im = 0.}

14voto

newacct Punkte 114757

Es steht genau im OCaml-Handbuch, Abschnitt 6.7, scrolle nach unten, direkt vor Abschnitt 6.7.1. Die Prioritätstabelle enthält einige Dinge wie +..., zu denen alle benutzerdefinierten mit + beginnenden Operatoren gehören. Es stimmt nicht, dass es immer vom ersten Zeichen abhängt, da **... eine höhere Priorität hat als *....

13voto

dbarbosa Punkte 2819

Im Allgemeinen basiert die Assoziativität und Präzedenz eines Operators (es sei denn, Sie verwenden camlp4 oder ähnliches) auf dem ersten Zeichen des Operators.

Quelle (suchen Sie nach "Assoziativität und Präzedenz für benutzerdefinierte Operatoren").

Es gibt keine Möglichkeit, dies explizit in OCaml zu definieren (siehe diesen Link und auch "Benutzerdefinierte Infix-Operatoren" auf Vergleich von Objective Caml und Standard ML)

Sie können camlp4 oder camlp5 verwenden, um die Reihenfolge der Infix-Funktionen explizit festzulegen. Es scheint, dass auch pa_do eine Option sein kann.

Ich habe versucht, ein Beispiel zu schreiben, aber ich bin nicht mit camlp4 vertraut und es ist nicht einfach, es in wenigen Minuten zu lernen.

3voto

hcarty Punkte 1671

Die Pa-Do-Syntax-Erweiterung für OCaml behandelt genau dieses Problem:

http://pa-do.forge.ocamlcore.org/

Sie können sie verwenden, um die Operatorpräzedenz zu ändern oder, in diesem Fall nützlicher, den expliziten Kontext zu verwenden, um die Bedeutung von Operatoren zu ändern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X