为什么 OCaml 的 (+) 不是多态的?

发布于 2024-12-14 07:41:31 字数 118 浏览 0 评论 0原文

我是 OCaml 新手。我喜欢 OCaml 的速度,但我不完全理解它的设计。例如,我希望 + 运算符具有多态性以支持整数、浮点数等。

为什么我们需要+.

I am an OCaml newbie. I like OCaml's speed but I don't fully understand its design. For example, I would like the + operator to be polymorphic to support integer, float and so on.

Why do we need +.?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鹿港小镇 2024-12-21 07:41:31

我希望“+”运算符具有多态性以支持整数、浮点数等。为什么我们需要“+”?

很好的问题。这里涉及许多微妙的权衡。

不重载运算符(如在 OCaml 中)的优点是:

  • 类型推断更简单且更可预测。
  • 代码更具可组合性:将代码从一个地方移动到另一个地方不会影响其含义。
  • 可预测的性能:您始终确切地知道正在调用哪个函数。

缺点是:

  • 不同运算符的数量很快就会失去控制:+ 代表 int+. 代表 float , +/ 表示任意精度有理数,+| 表示向量,+|| 表示矩阵和复数、低维向量和矩阵、齐次坐标等。

一些替代方案是:

I would like the '+' operator to be polymorphic to support integer, float and so on. Why do we need '+.'?

Excellent question. There are many subtle trade-offs involved here.

The advantages of not overloading operators (as in OCaml) are:

  • Type inference is simpler and more predictable.
  • Code is more composable: moving code from one place to another cannot affect its meaning.
  • Predictable performance: you always know exactly which function is being invoked.

The disadvantages are:

  • Number of different operators quickly gets out of control: + for int, +. for float, +/ for arbitrary-precision rationals, +| for vectors, +|| for matrices and the complex numbers, low-dimensional vectors and matrices, homogeneous coordinates etc.

Some alternatives are:

叶落知秋 2024-12-21 07:41:31

除了比较运算符之外,OCaml 不支持多态运算符(数字或其他)。 ++. 的对比消除了许多细微的错误,这些错误可能会在来回转换不同大小的整数、浮点数和其他数字类型时出现。它还意味着编译器始终准确地知道正在使用哪种数字类型,从而更容易识别程序员何时对始终具有整数值的数字做出了错误的假设。要求在数字类型之间进行显式转换可能看起来很尴尬,但从长远来看,它可能会为您节省更多的时间来跟踪奇怪的错误,而不是花费额外的时间来显式地编写。

除了数字运算符的 . 版本之外,我不认为 OCaml 语法特别奇怪。它与以前的 ML 语言非常一致,为其添加的功能提供了适当且合理的语法扩展。如果您一开始觉得很奇怪,那可能只是表明您到目前为止只使用语法密切相关的语言进行编程。当您学习新语言时,您会发现有许多不同的方法来使用语言语法,这些方法具有不同的优点和缺点,但其中很多只是某人决定的任意约定。

OCaml does not support polymorphic operators (numeric or otherwise) other than comparison operators. The + versus +. thing removes a lot of subtle bugs which can crop up in converting different sizes of integers, floats, and other numeric types back and forth. It also means that the compiler always knows exactly which numeric type is in use, thus making it easier to recognize when the programmer has made incorrect assumptions about a number always having an integer value. Requiring explicit casting between numeric types may seem awkward, but in the long run, it probably saves you more time tracking down weird bugs than you have to spend to write that extra period to be explicit.

Aside from the . versions of the numeric operators, I do not think that the OCaml syntax is particularly strange. It is very much in line with previous ML languages with appropriate and reasonable syntax extensions for its added features. If it initially seems odd to you, that probably simply indicates that you have been, thus far, only been programming in languages with closely related syntax. As you learn new languages, you will see that there are many different ways to have language syntax with different benefits and detriments, but a lot of it is just arbitrary conventions which someone decided on.

七分※倦醒 2024-12-21 07:41:31

基本上,SML 和 OCaml 的类型系统(忽略对象系统和模块)不支持即席多态性。这是一个设计决定。与 SML 不同,OCaml 还决定不包含算术语法糖。

ML 系列中的某些语言在数字运算符中具有极其有限的临时多态性形式。例如,标准机器学习中的 (+) 具有默认类型 (int, int) -> int,但类型为 (float, float) -> float 如果其参数或返回类型已知float。这些运算符在 SML 中很特殊,如果尚未内置,则无法定义它们。也不可能为其他值赋予此属性。 val add = (+) 的类型为 (int, int) -> int。这里的特殊性仅限于语言的语法,类型系统中不支持临时多态性。

OCaml 有一些具有特殊语义的运算符(但数字运算符不在其中),例如 ||&& 是短路的(但会变长) -电路(如果将它们分配给中间值)

let long_circuit_or = (||);;
let print_true x = print_string x; true;;
(* just prints "4" *)
print_true "4" || print_true "5";;
(* prints "45" *)
long_circuit_or (print_true "4") (print_true "5");;

Basically, the type systems of SML and OCaml (ignoring the object system and modules) do not support ad hoc polymorphism. This is a design decision. OCaml also, unlike SML, decided against including syntactic sugar for arithmetic.

Some languages in the ML family have extremely limited forms of ad hoc polymorphism in numeric operators. For instance, (+) in Standard ML has a default type of (int, int) -> int, but has type (float, float) -> float if its argument or return type is known to be float. These operators are special in SML, and could not be defined if they were not already built in. It also isn't possible to endow other values with this property. val add = (+) would have type (int, int) -> int. The specialness here is confined to the syntax of the language, there is no support for ad hoc polymorphism in the type system.

OCaml has a handful of operators with special semantics (but numeric operators are not among them), for instance || and && are short-circuit (but become long-circuit if you assign them to an intermediate value)

let long_circuit_or = (||);;
let print_true x = print_string x; true;;
(* just prints "4" *)
print_true "4" || print_true "5";;
(* prints "45" *)
long_circuit_or (print_true "4") (print_true "5");;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文