¿Cómo se relacionan los funtores en Haskell con los funtores en la teoría de categorías?
functor category-theory (3)
Sí, todas las instancias de Functor
son endofunctores en Hask; de hecho, son endofunctores de todo Hask a una subcategoría adecuada cuyos objetos son los tipos obtenidos al aplicar un constructor de tipo particular. Ese tipo de constructor es a lo que se asocia la instancia de Functor
, y proporciona la asignación para objetos; el mapeo para los morfismos es fmap
, que (debido a que solo nos interesan los endofunctores en una categoría cerrada cartesiana) es en sí misma una familia de morfismos en Hask .
Tiene sentido considerar otros funtores además de los que pueden tener instancias de Functor
, como funtores contravariantes (desde Hask hasta su categoría opuesta). La función arr
en la clase Arrow
también corresponde a un functor, de todo Hask a la categoría cuyos objetos son iguales a los de Hask y cuyos morfismos están descritos por el constructor de tipo con el que está asociada la instancia de Arrow
.
También son posibles otras generalizaciones (como señala Daniel Wagner), pero tienden a ser cada vez más difíciles de usar.
Por lo que entiendo, un functor es un mapeo entre dos categorías, por ejemplo, desde objetos en C http://mathurl.com/32qch9w.png a objetos en D http://mathurl.com/36b8r37.png donde C http://mathurl.com/32qch9w.png y D http://mathurl.com/36b8r37.png son categorías.
En Haskell hay Hask en el que los objetos son tipos de Haskell y los morfismos son funciones de Haskell. Sin embargo, la clase de tipo Functor
tiene una función fmap
que se asigna entre estos tipos (que son objetos y no categorías en sí):
fmap :: (a -> b) -> f a -> f b
fa
y fb
son objetos en Hask . ¿Significa esto que cada instancia de Functor
en Haskell es un endofunctor, y si no es así, Functor
realmente representa un functor?
¿Que me estoy perdiendo aqui? ¿Los tipos también son categorías en Haskell?
Un punto importante sobre esto es que lo que realmente desea son los funtores enriquecidos en Hask , no solo los funtores antiguos. Hask es cartesiano cerrado ( no realmente , pero trata de serlo), y por lo tanto se enriquece naturalmente en sí mismo.
Ahora, los endofunctores enriquecidos le brindan una forma de restringirlos a aquellos implementables dentro del lenguaje : un funtor enriquecido Hask -> Hask es una función en el nivel de objetos (tipos) fa
y para cada par de objetos a, b
un morfismo en Hask en marcha f: Hask (a, b) -> Hask (fa, fb) . Por supuesto, esto es solo fmap :: (a -> b) -> fa -> fb
Una instancia de Functor
especifica dos cosas: un constructor de tipo F
del tipo * -> *
, es decir, un mapeo de objetos de Hask a objetos de Hask, y una función de tipo (a -> b) -> (F a -> F b)
, es decir, una asignación de flechas de Hask a flechas de Hask compatibles con la asignación de objetos F
Entonces, sí, todas las instancias de Functor
son endofunctores. Hay varias generalizaciones disponibles en Hackage, por ejemplo, Control.Categorical.Functor .