2010-06-05 3 views
11

Я хочу, чтобы хорошие операторы для сложной арифметики сделали мой код более удобочитаемым. Ocaml имеет комплексный модуль, поэтому я просто хочу добавить операторов, которые называют эти функции.Как Ocaml решает приоритет для пользовательских операторов?

Самый интуитивный способ для меня - создать новый сложный оператор из всех обычных операторов, добавив «&» к символу оператора. Таким образом, + & и * & будут сложными сложениями и умножениями. Мне также хотелось бы, чтобы ~ & было сложным сопряжением.

Если я собираюсь использовать эти операторы, я хочу, чтобы они связывались так же, как и обычные арифметические отношения. На основе следующих сеансов они автоматически ведут себя так, как я хочу, но я хотел бы понять, почему, так что я не получаю ужасных ошибок, когда я вводил больше операторов.

Мое последнее предположение заключается в том, что их приоритет осуществляется путем лексической сортировки символов оператора в соответствии с порядком, который согласуется с обычным арифметическим приоритетом. Но я не могу это подтвердить.

Сессия один:

# 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.} 

Сессия два:

# 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.} 

ответ

13

В общем, ассоциативность и приоритет оператора (если вы не выходите на camlp4 или что-то) основывается на первый символ оператора.

source (ищите «приоритет ассоциативности для пользовательского оператора»).

Там нет никакого способа определить это явно в OCaml (см this а также «определенный пользователь операторы инфиксной» на Comparing Objective Caml and Standard ML)

Вы можете использовать camlp4 или camlp5 явно определить порядок инфиксных. Похоже, что pa_do также может быть вариантом.

Я попытался написать пример, но я не знаком с camlp4, и это нелегко узнать за несколько минут.

+0

Спасибо! Меня раздражает то, что правильный ответ не более полезен и/или потрясающий. Я тоже недостаточно знаком с p4/p5, чтобы использовать его. – forefinger

+2

Отличная ссылка (и). Я хотел бы упомянуть camlp {4,5}, но установление приоритета операторов было только средним в исходном вопросе. Конец должен был сделать код перспективным.Я сомневаюсь, что любое решение, связанное с camlp {4,5}, является хорошим решением для этой цели; это, безусловно, зависимость, которую я стараюсь избегать, хотя это часто заманчиво. –

14

Правильно в руководстве OCaml, section 6.7, прокрутите вниз, прямо перед разделом 6.7.1. В таблице приоритета есть некоторые вещи, такие как +..., который включает любые пользовательские значения, начиная с +. Неверно, что он всегда зависит от первого символа, так как **... имеет более высокий приоритет, чем *....

3

PA-сделать расширение синтаксиса для OCaml обращается именно этот вопрос:

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

Вы можете использовать его для изменения приоритета операторов, или, что более полезно в этом случае использовать явный контекст, чтобы изменить значение операторов.

Смежные вопросы