我知道OCaml不支持重载。那么,除了重载,我们可以采取什么方法来解决这个问题呢?
1)使用多态代替? 2)为不同的函数赋予不同的名称? 3)将同名函数放在不同的模块中?
哪一个会起作用?
1)使用多态代替? 2)为不同的函数赋予不同的名称? 3)将同名函数放在不同的模块中?
哪一个会起作用?
一切都取决于你对重载的定义。有几种用例,例如:
如果你想在处理整数以外的其他东西的数学表达式中使用通常的中缀运算符名称:在本地重新绑定你的运算符;模块和“local open”可以帮助实现这一点。
module I32 = struct
open Int32
let (+), (-), ( * ), (/), (!!) = add, sub, mul, div, of_int
end
... I32.(x + y * !!2) ...
如果你希望一个操作在使用数值类型时具有多态性,你需要在这样的数值运算中进行抽象。例如,通用的快速指数函数(由整数提供),可以用于矩阵等数据结构。let rec pow ( * ) one a = function
| 0 -> one
| n -> pow ( * ) (if n mod 2 = 0 then one else one * a) (a * a) (n / 2)
let () = assert (pow ( *.) 1. 2. 3 = 8.)
更一般地说,是的,想法是将您想要“重载”的操作符(这里是中缀操作符,但纯名称也可以,并且通常对于可读性更好)捕获为一组操作符,并传递和抽象化这些操作符的字典 - 实际上与 Haskell 类型类编译成的方式非常相似。
include
,那么这个I32
将包含所有的Int32
,因此在本地打开I32
将特别导入所有Int32
的定义。我不喜欢打开大范围的作用域,因为它会冒着遮蔽用户定义的风险。 - gasche