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和…
。但是你对结果是正确的,我这样重新定义了运算符,它进入了一个循环。干杯!