Я смотрю OCaml функторы. Он выглядит очень похожим на так называемые общие объекты в C++
/C#
/Java
. Если вы проигнорируете стирание Java-типа на данный момент и проигнорируете детали реализации для шаблонов С++ (меня интересует функция языка), функторы довольно специфичны для дженериков.
Если я правильно ее понимаю, функтор дает вам новый набор функций из типа, который вы предоставляете, чтобы, например,
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);}
}
Конечно, существует немного другое, поскольку функтор влияет на Module
(который представляет собой просто набор функций и значений типов, аналогичных пространству имен C#
).
Но так ли это? Являются ли функторы просто дженериками, применяемыми к пространствам имен? Или есть какие-то существенные различия между функторами и дженериками, которые мне не хватает.
Даже если функторы - это просто дженерики для пространства имен, каково существенное преимущество этого подхода? Классы также могут использоваться как специальные пространства имен с использованием вложенных классов.