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

时间:2011-11-25 17:26:33

标签: operators ocaml

在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

还知道如何修改一元(-)吗?

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中找到此代码。)

我认为没有办法在没有攻击编译器的情况下获得你想要的东西。