f# - ¿Podría por favor explicarme los funtores de OCaml?
functor (3)
Echa un vistazo a estas estructuras de datos en el curso de ocaml:
http://www.cs.cornell.edu/Courses/cs3110/2009fa/lecturenotes.asp
La conferencia del functor: http://www.cs.cornell.edu/Courses/cs3110/2009fa/lectures/lec10.html
y la implementación del árbol de distribución mediante functor: http://www.cs.cornell.edu/Courses/cs3110/2009fa/recitations/rec-splay.html
Posible duplicado:
En Programación Funcional, ¿qué es un functor?
No sé mucho sobre OCaml, he estudiado F # por algún tiempo y lo entiendo bastante.
Dicen que F # pierde el modelo de functor, que está presente en OCaml. He intentado averiguar qué es exactamente el funtor, pero la wikipedia y los tutoriales no me ayudaron mucho.
¿Podría por favor iluminar ese misterio para mí? Gracias por adelantado :)
EDITAR:
He captado el punto, gracias a todos los que me ayudaron. Puede cerrar la pregunta como duplicado exacto de: En la programación funcional, ¿qué es un functor?
Los funcionales son módulos parametrizados por módulos, es decir, una reflexión de módulos a módulos (la función ordinaria es la reflexión de valores a valores, la función polimórfica es la reflexión de los tipos a las funciones ordinarias).
Véase también ocaml-tutorial sobre módulos .
Los ejemplos en el manual también son útiles.
Si proviene de un universo OOP, entonces probablemente ayude pensar que un módulo es análogo a una clase estática. Similar a las clases estáticas .NET, el módulo OCaml tiene constructores; a diferencia de .NET, los módulos OCaml pueden aceptar parámetros en sus constructores. Un functor es un nombre que suena aterrador para el objeto que pasa al constructor de módulos.
Entonces, usando el ejemplo canónico de un árbol binario, normalmente lo escribiríamos en F # de esta manera:
type ''a tree =
| Nil
| Node of ''a tree * ''a * ''a tree
module Tree =
let rec insert v = function
| Nil -> Node(Nil, v, Nil)
| Node(l, x, r) ->
if v < x then Node(insert v l, x, r)
elif v > x then Node(l, x, insert v r)
else Node(l, x, r)
Fino y elegante. Pero, ¿cómo sabe F # cómo comparar dos objetos del tipo ''a
usando los operadores <
y >
?
Detrás de las escenas, está haciendo algo como esto:
> let gt x y = x > y;;
val gt : ''a -> ''a -> bool when ''a : comparison
Bien, bien, ¿qué sucede si tiene un objeto de tipo Person
que no implementa esa interfaz en particular? ¿Qué tal si quisieras definir la función de clasificación sobre la marcha? Un enfoque es simplemente pasar el comparador de la siguiente manera:
let rec insert comparer v = function
| Nil -> Node(Nil, v, Nil)
| Node(l, x, r) ->
if comparer v x = 1 then Node(insert v l, x, r)
elif comparer v x = -1 then Node(l, x, insert v r)
else Node(l, x, r)
Funciona , pero si está escribiendo un módulo para operaciones de árbol con inserción, búsqueda, eliminación, etc., necesita que los clientes pasen una función de pedido cada vez que llamen algo.
Si F # admite functores, su sintaxis hipotética podría tener este aspecto:
type ''a Comparer =
abstract Gt : ''a -> ''a -> bool
abstract Lt : ''a -> ''a -> bool
abstract Eq : ''a -> ''a -> bool
module Tree (comparer : ''a Comparer) =
let rec insert v = function
| Nil -> Node(Nil, v, Nil)
| Node(l, x, r) ->
if comparer.Lt v x then Node(insert v l, x, r)
elif comparer.Gt v x then Node(l, x, insert v r)
else Node(l, x, r)
Aún en la sintaxis hipotética, crearías tu módulo como tal:
module PersonTree = Tree (new Comparer<Person>
{
member this.Lt x y = x.LastName < y.LastName
member this.Gt x y = x.LastName > y.LastName
member this.Eq x y = x.LastName = y.LastName
})
let people = PersonTree.insert 1 Nil
Desafortunadamente, F # no es compatible con los funtores, por lo que tiene que recurrir a algunas soluciones desordenadas. Para el escenario anterior, casi siempre almacenaría el "functor" en mi estructura de datos con algunas funciones auxiliares auxiliares para asegurarme de que se copie correctamente:
type ''a Tree =
| Nil of ''a -> ''a -> int
| Node of ''a -> ''a -> int * ''a tree * ''a * ''a tree
module Tree =
let comparer = function
| Nil(f) -> f
| Node(f, _, _, _) -> f
let empty f = Nil(f)
let make (l, x, r) =
let f = comparer l
Node(f, l, x, r)
let rec insert v = function
| Nil(_) -> make(Nil, v, Nil)
| Node(f, l, x, r) ->
if f v x = -1 then make(insert v l, x, r)
elif f v x = 1 then make(l, x, insert v r)
else make(l, x, r)
let people = Tree.empty (function x y -> x.LastName.CompareTo(y.LastName))