Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ocaml如何决定用户定义运算符的优先级?_Ocaml - Fatal编程技术网

Ocaml如何决定用户定义运算符的优先级?

Ocaml如何决定用户定义运算符的优先级?,ocaml,Ocaml,我想要复杂算术的好操作符,使我的代码更具可读性。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.}
#开放式综合体;;
#设(+&)ab=加上ab;;
val(+&):Complex.t->Complex.t->Complex.t=
#设(*&)ab=mul a b;;
val(*&):Complex.t->Complex.t->Complex.t=
#一+&零*&一+&零*&一;;
-:Complex.t={re=1;im=0.}
#零+一*&零+一*&零;;
-: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.}
#开放式综合体;;
#设(*&)ab=mul a b;;
val(*&):Complex.t->Complex.t->Complex.t=
#设(+&)ab=加上ab;;
val(+&):Complex.t->Complex.t->Complex.t=
#一+&零*&一+&零*&一;;
-:Complex.t={re=1;im=0.}
#零+一*&零+一*&零;;
-:Complex.t={re=0;im=0.}
#i+&i*&i+&i*&i*&i;;
-:Complex.t={re=-1;im=0.}
#设(&)a=conj a;;
val(~&):Complex.t->Complex.t=
#(一加一)*&&&(一加一);;
-:Complex.t={re=2;im=0.}
通常,运算符的关联性和优先级(除非您转到camlp4或其他内容)基于运算符的第一个字符

(查找“用户定义运算符的关联性优先级”)

无法在OCaml中显式定义它(请参阅上的“用户定义的中缀运算符”)

可以使用或显式定义中缀函数的顺序。这似乎也是一种选择


我试着写一个例子,但我不熟悉camlp4,几分钟内不容易学会。

它就在OCaml手册中,向下滚动,就在第6.7.1节之前。优先级表有一些内容,如
+…
,其中包括以
+
开头的任何用户定义的内容。它并不总是取决于第一个字符,因为
**…
的优先级高于
**…

OCaml的pa do语法扩展正好解决了这个问题:


您可以使用它来更改运算符优先级,或者更有用的是,使用显式上下文来更改运算符的含义。

谢谢!我有点恼火,因为正确的答案没有更有用和/或更棒。我对p4/p5也不太熟悉,无法使用它。很好的链接。我本想提到camlp{4,5},但确定运算符的优先级只是原始问题中的一个平均值。最终目的是让代码成为未来的证明。我怀疑任何涉及camlp{4,5}的解决办法都是实现这一目标的好办法;这当然是我试图避免的一种依赖,尽管它常常很诱人。