Как Ocaml определяет приоритет для пользовательских операторов? - PullRequest
11 голосов
/ 06 июня 2010

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

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

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

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

Сессия первая:

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

Ответы [ 3 ]

14 голосов
/ 06 июня 2010

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

13 голосов
/ 06 июня 2010

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

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

Нет способа явно определить его в OCaml (см. this , а также "Пользовательские инфиксные операторы" в Сравнение Objective Caml и Standard ML )

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

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

3 голосов
/ 21 сентября 2010

Расширение синтаксиса pa-do для OCaml решает именно эту проблему:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...