我在看OCaml 的 functors。C++
在我看来,它与/ C#
/中所谓的通用对象非常相似Java
。如果您暂时忽略 Java 的类型擦除,并忽略 C++ 模板的实现细节(我对语言特性感兴趣),函子与泛型完全一致。如果我理解正确,仿函数会根据您提供的类型为您提供一组新的函数,例如
List<MyClass>.GetType() != List<MyOtherClass>.GetType()
但是你可以粗略地重写 OCaml 的
#module Set =
functor (Elt: ORDERED_TYPE) ->
struct
type element = Elt.t
type set = element list
let empty = []
let rec add x s =
match s with
[] -> [x]
| hd::tl ->
match Elt.compare x hd with
Equal -> s (* x is already in s *)
| Less -> x :: s (* x is smaller than all elements of s *)
| Greater -> hd :: add x tl
let rec member x s =
match s with
[] -> false
| hd::tl ->
match Elt.compare x hd with
Equal -> true (* x belongs to s *)
| Less -> false (* x is smaller than all elements of s *)
| Greater -> member x tl
end;;
进入C#
class Set<T> where T : ISortable
{
private List<T> l = new List<T>();
static public Set<T> empty = new Set<T>();
public bool IsMember(T x) {return l.IndexOf(x) > -1;}
public void Add(T x) {l.Add(x);}
}
当然有一点不同,因为仿函数会影响 a Module
(这只是一堆类型函数和值定义,类似于C#
's 命名空间)。
但仅此而已吗?函子仅仅是应用于命名空间的泛型吗?或者我缺少的仿函数和泛型之间是否有任何显着差异。
即使仿函数只是命名空间的泛型,这种方法的显着优势是什么?类也可以用作使用嵌套类的临时命名空间。