Functional programming 重新定义中缀运算符

Functional programming 重新定义中缀运算符,functional-programming,ocaml,Functional Programming,Ocaml,我在学习 有一个关于重新定义中缀运算符的问题 书中有这样一段话: # let (+) = ( * ) and (-) = (+) and ( * ) = (/) and (/) = (-);; val + : int > int > int = <fun> val - : int > int > int = <fun> val * : int > int > int = <fun&

我在学习

有一个关于重新定义中缀运算符的问题


书中有这样一段话:

# let (+) = ( * )
      and (-) = (+)
      and ( * ) = (/)
      and (/) = (-);;
  val + : int > int > int = <fun>
  val - : int > int > int = <fun>
  val * : int > int > int = <fun>
  val / : int > int > int = <fun>
# 5 + 4 / 1;;
-: **int = 15**
#让(+)=(*)
和(-)=(+)
和(*)=(/)
和(/)=(-);;
val+:int>int>int=
val-:int>int>int=
val*:int>int>int=
val/:int>int>int=
# 5 + 4 / 1;;
-:**int=15**

首先,这些重新定义是如何工作的?

对我来说,函数似乎是在一种不确定的循环中运行的,因为所有的操作似乎都是重新定义和连接的

例如,如果我做
1+2
,那么它将是
1*2
,因为
(*)=(/)
,它将是
1/2
,因为
(/)=(
,那么它将是
1-2
,依此类推我说得对吗?


其次,
5+4/1
的结果是否为
15
,即使在重新定义过程中只执行了一步功能?

因此,假设重新定义将进一步执行,即,
1+2
仅为
1*2
,不再进行转换,因此
5+4/1
应为
5*4-1
,对吗?那么答案是
19
我说的对吗?

对我来说,这些函数似乎是以一种不确定的方式运行的 循环,因为所有操作看起来都是重新定义和连接的

不是真的,它只是同时重新定义中缀运算符(使用
关键字)。您看到的是而不是递归定义。在OCaml中,递归定义是使用let rec(您可能已经知道)

对于问题的第二部分,我认为这是一个运算符优先级的问题。请注意,在原始表达式中,
5+4/1
实际上是遵循算术运算符的常规优先规则的
5+(4/1)
。因此,我认为转换只是保留了这种绑定(某种程度上)。你会得到
5*(4-1)=15
关键的观察结果(IMHO)是
(+)
是由先前存在的
(*)
定义的,而不是几行之后出现的定义。类似地,
(*)
是由先前存在的
(/)
定义的。正如Asiri所说,这是因为使用了
let
,而不是
let rec

同样,在OCaml中,优先级和关联性是运算符固有的,不能通过定义来更改。优先级和结合性由运算符的第一个字符决定


如果您查看中的运算符优先级和关联性表,您将看到所有条目都是为“以字符X开头的运算符”定义的。

+1,我认为即使我们通过重新定义来更改
+
的“含义”,我们也无法更改它的关联性,这是由表达式的静态形式决定的(根据您指出的表格).干杯!好的,根据运算符的第一个字符,优先级和关联性都是固定的。我将更新我的答案。那么你的意思是如果我使用let rec,那么答案就不同了?我的意思是它将是我想象的吗?@JacksonTale:是的,但是你将无法按原样使用
rec
(我试过了,编译器不喜欢它)。相反,你必须做
let(+)xy=x*y和…
。但是你对结果是正确的,我这样重新定义了运算符,它进入了一个循环。干杯!