Ocaml中的重载

Ocaml中的重载,ocaml,overloading,ml,Ocaml,Overloading,Ml,我知道OCaml不支持重载。那么,我们可以做些什么来解决这个问题,而不是过载 1) 改用多态性? 2) 给不同的函数取不同的名字? 3) 将相同名称的函数放在不同的模块中 哪种方法有效?这完全取决于你所说的重载是什么意思。有几个用例,例如: 如果您想在数学表达式中使用常用的中缀运算符名称来处理整数以外的内容:在本地重新绑定运算符;模块和“本地开放”可以帮助实现这一点 module I32 = struct open Int32 let (+), (-), ( * ), (/), (!!)

我知道OCaml不支持重载。那么,我们可以做些什么来解决这个问题,而不是过载

1) 改用多态性? 2) 给不同的函数取不同的名字? 3) 将相同名称的函数放在不同的模块中


哪种方法有效?

这完全取决于你所说的重载是什么意思。有几个用例,例如:

如果您想在数学表达式中使用常用的中缀运算符名称来处理整数以外的内容:在本地重新绑定运算符;模块和“本地开放”可以帮助实现这一点

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”,如果您在模块I32中做了一个“include Int32”,会有什么不同?在这种情况下,它们本质上是等价的吗?@anecodeal:那将是非常不同的:如果我使用
include
,这个
I32
将包括所有
Int32
,因此在本地打开
I32
将特别导入
Int32
的所有定义。我不喜欢
打开
大范围,因为它有隐藏用户定义的风险。