2010-06-05 15 views
11

Quiero buenos operadores para la aritmética compleja para hacer que mi código sea más legible. Ocaml tiene un módulo complejo, así que solo quiero agregar operadores que llamen esas funciones.¿Cómo decide Ocaml la precedencia para los operadores definidos por el usuario?

La manera más intuitiva para mí es hacer un nuevo operador complejo de todos los operadores habituales agregando '&' al símbolo del operador. Por lo tanto + & y * & serán una adición y multiplicación complejas. También me gustaría que ~ & sea una conjugación compleja.

Si voy a utilizar estos operadores, quiero que se asocien de la misma manera que la aritmética normal se asocia. En base a las siguientes sesiones, se comportan automáticamente de la manera que yo quiero, pero me gustaría entender por qué, para no tener errores horribles cuando presento más operadores.

Mi conjetura actual es que su precedencia se hace ordenando léxicamente los símbolos del operador de acuerdo con un orden que sea consistente con la precedencia aritmética normal. Pero no puedo confirmar esto.

Sesión uno:

# open Complex;; 
# let (+&) a b = add a b;; 
val (+&) : Complex.t -> Complex.t -> Complex.t = <fun> 
# let (*&) a b = mul a b;; 
val (*&) : Complex.t -> Complex.t -> Complex.t = <fun> 
# 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.} 

Sesión dos:

# open Complex;; 
# let (*&) a b = mul a b;; 
val (*&) : Complex.t -> Complex.t -> Complex.t = <fun> 
# let (+&) a b = add a b;; 
val (+&) : Complex.t -> Complex.t -> Complex.t = <fun> 
# 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 = <fun> 
# (one +& i) *& ~& (one +& i);; 
- : Complex.t = {re = 2.; im = 0.} 

Respuesta

13

En general, la asociatividad y precedencia de un operador (a menos que vaya a camlp4 o algo así) se basa en la primer personaje del operador.

source (busque "Prioridad de asociatividad para el operador definido por el usuario").

No hay manera de definir explícitamente en OCaml (ver también "this y operadores infijos definidos por el usuario" en la Comparing Objective Caml and Standard ML)

Usted puede utilizar camlp4 o camlp5 definir explícitamente el orden de la función infija. Parece que pa_do también puede ser una opción.

Intenté escribir un ejemplo pero no estoy familiarizado con camlp4 y no es fácil de aprender en unos minutos.

+0

Gracias! Me molesta un poco que la respuesta correcta no sea más útil y/o sorprendente. Yo tampoco estoy lo suficientemente familiarizado con p4/p5 para usarlo. – forefinger

+2

Great link (s). Iba a mencionar camlp {4,5}, pero fijar la precedencia de los operadores fue solo un medio en la pregunta original. El final fue hacer que el código fuera a prueba del futuro.Dudo que cualquier solución que involucre camlp {4,5} sea una buena solución para este objetivo; sin duda es una dependencia que trato de evitar, aunque a menudo es tentador. –

14

Está en el manual OCaml, section 6.7, desplácese hacia abajo, justo antes de la sección 6.7.1. La tabla de precedencia tiene algunas cosas como +..., que incluye cualquier definido por el usuario que comience con +. No es cierto que siempre dependa del primer carácter, ya que **... tiene una precedencia mayor que *....

3

La extensión sintaxis pa-hacer por OCaml aborda precisamente este tema:

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

Se puede utilizar para cambiar la precedencia de operadores, o, más útil en este caso, usar el contexto explícito para cambiar el significado de operadores.

Cuestiones relacionadas