You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在SML中使用重载运算符定义函数未出现预期报错?

问题

我正在阅读Colin Myers、Chris Clack和Ellen Poon所著的《Programming with Standard ML》,在§2.4.1「受限多态函数」章节中提到:

与运算符=和<>不同,>、<等其他比较运算符是重载的,它们并非受限多态,因此如下函数定义会失败:

- fun wrong_ordered (x, y, z)
     = (x < y) andalso (y < z);
Error: overloaded variable "<" cannot be resolved

失败原因是SML无法确定x、y、z的类型。但我在SML/NJ 110.99.2和Poly/ML 5.9中输入该定义时未收到错误,定义成功并返回:

- fun wrong_ordered (x, y, z) = (x < y) andalso (y < z);
val wrong_ordered = fn : int * int * int -> bool

请问为何未出现书中所述的报错?

解答

这是因为现代SML编译器(包括你使用的SML/NJ和Poly/ML)实现了重载类型的默认推断规则,而书中描述的是早期标准ML或更严格的编译器行为。

具体细节:

  • 早期标准ML规范中,重载运算符(如<、>)没有默认类型绑定,编译器无法自动推断未指定类型的重载变量类型,因此会抛出"overloaded variable cannot be resolved"的错误。
  • 现代编译器为提升易用性,给重载的数值比较运算符添加了默认类型——int。当编译器无法从上下文推断出具体类型时,会自动将这些重载运算符绑定到int类型,所以你的函数会被推断为接受int * int * int参数并返回bool,不会报错。

你可以验证这一点:显式指定非int类型时,编译器会正确推断对应类型,比如:

fun wrong_ordered (x: real, y: real, z: real) = (x < y) andalso (y < z);

此时函数类型会被推断为real * real * real -> bool,无任何问题。只有当没有上下文或显式类型标注时,现代编译器才会默认用int解析重载的比较运算符。

内容的提问来源于stack exchange,提问作者Flux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:05:21