Ocaml中的重载

8
我知道OCaml不支持重载。那么,除了重载,我们可以采取什么方法来解决这个问题呢?
1)使用多态代替? 2)为不同的函数赋予不同的名称? 3)将同名函数放在不同的模块中?
哪一个会起作用?
1个回答

18

一切都取决于你对重载的定义。有几种用例,例如:

如果你想在处理整数以外的其他东西的数学表达式中使用通常的中缀运算符名称:在本地重新绑定你的运算符;模块和“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 类型类编译成的方式非常相似。


我注意到在模块I32中你使用了'open Int32',如果你改用'include Int32'会有什么不同呢?在这种情况下它们是本质上等价的吗? - aneccodeal
1
@aneccodeal:这将非常不同:如果我使用include,那么这个I32将包含所有的Int32,因此在本地打开I32将特别导入所有Int32的定义。我不喜欢打开大范围的作用域,因为它会冒着遮蔽用户定义的风险。 - gasche

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接