在OCaml中,访问二进制运算符非常容易,例如“+”:
# (+);;
( + ) : int -> int -> int
按照我的意愿修改它们:
# let (+) = (+.);;
( + ) : float -> float -> float
在Pervasives文档中,它说(~-)
是与(-)
对应的一元运算符,表示~-5
返回- :int = -5
。
也很容易修改(~-)
:
let (~-) = (~-.);;
(~-) : float -> float
幸运的是,OCaml允许用户使用(-)
作为(~-)
的别名:
假设我们已定义
foo : int -> int -> int
我们可以致电
foo 1 (-1);;
这比
更好foo 1 (~-1);;
嗯,问题是,当我更改(~-)
定义时,它不会影响一元运算符(-)
......
let (~-) x = 5;;
~-2;;
- : int = 5
-2;;
- : int = -2
还知道如何修改一元(-)
吗?
答案 0 :(得分:8)
正如你所说,一元(-)
是(~-)
的捷径。实际上,您的更改影响了一元(-)
;例如,在覆盖(-)
后,您可以通过多种方式使用(~-)
:
# - (2+0);;
- : int = 0
# let a = 2;;
val a : int = 2
# -a;;
- : int = 0
因此,当您将表达式传递给(-)
时,它会起作用。如果您调用-2
,它将被解析为值,而不是函数应用程序。遵循负数的正常惯例是有道理的。
(-)
,因此可能会导致混淆和奇怪的错误。
答案 1 :(得分:3)
以下是编译器的代码摘录,似乎可以处理这种情况。请注意,它仅适用于浮点常量。这不是-
运算符的一般功能。
signed_constant:
constant { $1 }
| MINUS INT { Const_int(- $2) }
| MINUS FLOAT { Const_float("-" ^ $2) }
| MINUS INT32 { Const_int32(Int32.neg $2) }
| MINUS INT64 { Const_int64(Int64.neg $2) }
(您将在parser.mly中找到此代码。)
我认为没有办法在没有攻击编译器的情况下获得你想要的东西。