Estoy buscando OCaml's functors. Me parece bastante idéntica a los llamados objetos genéricos en C++
/C#
/Java
. Si por ahora ignora la borradura de tipos de Java e ignora los detalles de implementación para las plantillas de C++ (me interesa la función de idioma), los funtores son bastante idénticos a los genéricos. Si he entendido bien, funtor le da un nuevo conjunto de funciones de un tipo que proporciona, de manera que, por ejemplo,Cuál es la diferencia entre functors y "genéricos"
List<MyClass>.GetType() != List<MyOtherClass>.GetType()
Pero más o menos podría reescribir de
#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;;
en 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);}
}
Claro que hay una ligera diferencia ya que un functor afecta a Module
(que es solo un montón de tipos de función y valor es definiciones, similar al espacio de nombre C#
).
¿Pero es solo eso? ¿Los funtores son meramente genéricos aplicados a los espacios de nombres? ¿O hay alguna diferencia significativa entre los funtores y los genéricos que me falta?
Incluso si los funtores son solo genéricos para el espacio de nombres, ¿cuál es la ventaja significativa de ese enfoque? Las clases también se pueden usar como espacios de nombres ad-hoc utilizando clases anidadas.
C++ y C# son diferentes en el aspecto del sistema de tipos? No veo cómo, en la línea inferior tiene un nuevo tipo de lista si es compatible con la máquina virtual o se genera automáticamente en tiempo de compilación. Ilumíname. –
De nada. plantilla clase X { T t; public: int hello() {return t.hello(); } }; clase Hola {public: int hello() {return 1; }}; int main() { X x; return x.hello(); } –
ygrek
Tal vez soy un poco denso, pero no lo conseguí. En su ejemplo tiene clase Hola y una clase del tipo X, como en C#. Verifiqué que imprime 1 como se esperaba http://codepad.org/vZUPwFgs cuál es la diferencia en el aspecto del sistema tipo en el ejemplo que proporcionó (por supuesto, usó tipos que no son de referencia y que solo puede usar en C++, pero a excepción de eso no veo la diferencia). –