Haskell tiene una noción de "funciones genéricas" que tiene cierta similitud aparente con el lisp común: al no tener experiencia con Haskell ni con el lisp común, podría ser muy aproximado aquí. Esto significa que se puede definir una to_string
instalación genérica para definir una representación de cadena para todos los tipos. Por supuesto, la facilidad tiene que definirse en los casos especiales, pero hay una to_string
función cuya firma es α → string
.
¿Se borran los tipos en Haskell, como en OCaml? En caso afirmativo, ¿cómo difiere la implementación de "funciones genéricas" en Haskell de la de lisp común, donde los tipos son dinámicos y, por lo tanto, no se borran?
Entiendo que los detalles de implementación son específicos del compilador, pero probablemente hay disposiciones comunes a muchas o todas las implementaciones.
fuente
a -> String
. Lo más probable es que tenga una restricción de tipo, comoShow a => a -> String
.Respuestas:
La respuesta hasta ahora es engañosa.
Es necesario hacer una distinción entre polimorfismo "paramétrico" y "sobrecarga ad-hoc". Paramétrico significa "se comporta de manera uniforme para todos los tipos a", mientras que "ad-hoc", a lo que Simon se refiere como polimórfico, cambia la implementación en función del tipo.
Ejemplos de ambos son
reverse :: [a] -> [a]
, que es paramétrico yshow :: Show a => a -> String
que está "ad-hoc" sobrecargado.Si desea una intuición más abstracta, creo que es útil considerar las clases de verbos del lenguaje natural que "funcionan" para todos los objetos, como "poseer" o "pensar" que no imponen restricciones al objeto, pero " abrir "requiere que de lo que estamos hablando se pueda abrir. Puedo "pensar en una puerta" y "abrir una puerta", mientras que no tiene sentido, por ejemplo, "abrir un árbol". Tomar el ejemplo aún más "abrir" es "polimórfico ad-hoc" como "abrir una ventana" y "abrir un ticket de queja con el servicio al cliente" son dos cosas muy diferentes. Si esto parece forzado, ¡olvídalo! Esto funciona para mi.
Sin embargo, ambos se resuelven en tiempo de compilación y de hecho se "borran". Modulo de varias extensiones de GHC y Template Haskell, etc. De hecho , los tipos se borran en tiempo de compilación y nunca se inspeccionan en tiempo de ejecución.
Las funciones polimórficas paramétricas se comportan de manera idéntica para todos los tipos, por lo que solo se debe generar una pieza de código, mientras que el compilador decide en el momento de la compilación qué versión de una función "clasificada por tipo" debe ejecutarse en un punto de programa particular. Esta es también la razón por la cual existe la restricción de una instancia por tipo por clase de tipo y la solución alternativa "newtype" correspondiente.
La implementación se detalla en el libro de texto de SPJ y el documento de Wadler y Blotts sobre clases de tipos .
fuente
forall
extensión GHC ).advertencia: mi experiencia en CS no es muy sólida, por lo que no siempre uso el vocabulario correcto, y podría estar equivocado en algunos puntos. De todos modos, aquí está mi entendimiento:
Creo que estás confundiendo genéricos con polimorfismo.
Los tipos genéricos como los que
List<Foo>
se usan para describir los tipos que toman otros tipos como parámetro y permiten una verificación de tipos más rica.Una función genérica en Haskell podría ser
count:: List a -> Int
. Acepta listas de cualquier tipo y devuelve el número de elementos. Solo hay una implementación.Por lo general, al definir Lista, no puede asumir nada sobre T. Solo puede almacenarlo y devolverlo.
Su
to_string
función es una función polimórfica, lo que significa que se comportará de manera diferente en diferentes circunstancias. En haskell, esto se hace con typeclasses, que funciona como adjetivos para tipos.Tiene una
Show
clase de tipo, que define unashow :: a -> String
función.Cuando un tipo
Foo
implementa laShow
clase de tipo, debe proporcionar la definición deshow
. Este tipo se puede usar en funciones que requieren elShow
calificador (como enShow a => a -> whatever
). Haskell no puede borrar tipos, ya que esas funciones tienen que encontrar la implementación correcta de lashow
función.fuente