如何修改OCaml中的一元运算符?

Rom*_*360 3 ocaml operators

在OCaml中,访问二进制运算符非常容易,例如"+":

# (+);;

( + ) : int -> int -> int
Run Code Online (Sandbox Code Playgroud)

并按我的意愿修改它们:

# let (+) = (+.);;

( + ) : float -> float -> float
Run Code Online (Sandbox Code Playgroud)

在Pervasives文档中,它表示(~-)对应的是一元运算符(-),意味着~-5返回- :int = -5.

它也很容易修改(~-):

let (~-) = (~-.);;

(~-) : float -> float
Run Code Online (Sandbox Code Playgroud)

幸运的是,OCaml允许用户(-)作为别名使用(~-):

假设我们已定义

foo : int -> int -> int
Run Code Online (Sandbox Code Playgroud)

我们可以打电话

foo 1 (-1);;
Run Code Online (Sandbox Code Playgroud)

哪个方式比

foo 1 (~-1);;
Run Code Online (Sandbox Code Playgroud)

好吧,问题是,当我改变(~-)定义时,它不会影响一元运算符(-)......

let (~-) x = 5;;

~-2;;
- : int = 5

-2;;
- : int = -2
Run Code Online (Sandbox Code Playgroud)

任何想法如何修改一元(-)

pad*_*pad 8

正如你所说,一元(-)是一个捷径(~-).实际上,你的改变影响了一元(-); 例如,(-)在覆盖后,您可以根据需要使用多种方法(~-):

# - (2+0);;
- : int = 0

# let a = 2;;
val a : int = 2
# -a;;
- : int = 0
Run Code Online (Sandbox Code Playgroud)

所以当你传递一个表达式时它会起作用(-).如果您调用-2,它将被解析为值,而不是函数应用程序.遵循负数的正常惯例是有意义的.

顺便说一句,我不建议您使用这种覆盖运算符的方式.由于您对(-)具有该运算符的任何数据类型进行了更改,因此可能会导致混淆和奇怪的错误.