我是OCaml新手。我喜欢OCaml的速度,但我并不完全了解它的设计。例如,我希望+
运算符是多态的,以支持整数,浮点数等。
为什么我们需要+.
?
答案 0 :(得分:25)
我希望'+'运算符是多态的,以支持整数,浮点数等。为什么我们需要'+。'?
很好的问题。这里涉及许多微妙的权衡。
不重载运算符(如在OCaml中)的优点是:
缺点是:
+
为int
,+.
为float
,任意精度为+/
,{{ 1}}用于向量,+|
用于矩阵和复数,低维向量和矩阵,齐次坐标等。一些替代方案是:
+||
和2.3/0
等错误。答案 1 :(得分:11)
Ocaml不支持比较运算符以外的多态运算符(数字或其他)。 +
与+.
之类的东西会消除许多微妙的错误,这些错误会在转换不同大小的整数,浮点数和其他数字类型时出现。这也意味着编译器总是确切地知道正在使用哪种数字类型,因此更容易识别程序员何时对一个始终具有整数值的数字做出错误的假设。要求在数字类型之间进行显式转换可能看起来很尴尬,但从长远来看,它可能会为您节省更多时间来追踪奇怪的错误,而不是花费额外的时间来明确写出这些错误。
除了数字运算符的.
版本之外,我认为Ocaml语法并不特别奇怪。它与之前的ML语言非常一致,并且为其增加的功能提供了适当且合理的语法扩展。如果它最初看起来很奇怪,那可能只是表明你到目前为止只是用语法编程紧密相关的语言进行编程。当你学习新语言时,你会发现有许多不同的方法可以让语言语法具有不同的好处和不利之处,但是很多方法只是某人决定的任意约定。
答案 2 :(得分:2)
基本上,SML和OCaml的类型系统(忽略对象系统和模块)不支持ad hoc多态。这是一个设计决定。与SML不同,OCaml决定不使用语法糖进行算术运算。
ML系列中的某些语言在数字运算符中具有极有限形式的ad hoc多态。例如,标准ML中的(+)
具有默认类型(int, int) -> int
,但如果其参数或返回类型已知为{{1},则类型为(float, float) -> float
}}。这些运算符在SML中是特殊的,如果它们尚未内置,则无法定义。也不可能使用此属性赋予其他值。 float
的类型为val add = (+)
。这里的特殊性仅限于语言的语法,类型系统中不支持ad hoc多态。
OCaml有一些具有特殊语义的运算符(但数字运算符不在其中),例如(int, int) -> int
和||
是短路的(但如果将它们分配给它们,则变为长电路中间值)
&&