haskell - ¿Qué hace exactamente el "derivador funcional"?
haskell maybe (2)
El código que realmente hace la escritura es, desafortunadamente, un poco en el lado peludo. Creo que eso se debe en gran parte a que, antes, el código más simple a veces conducía a tiempos de compilación excesivos. A Twan van Laarhoven se le ocurrió el código actual para resolver este problema.
La instancia de Functor
derivada siempre hace lo obvio. Esto usualmente está bien, pero ocasionalmente pierde oportunidades. Por ejemplo, supongamos que escribo
data Pair a = Pair a a deriving Functor
data Digit a = One a | Two a a deriving Functor
data Queue a =
Empty
| Single a
| Deep !(Digit a) (Queue (Pair a)) !(Digit a) deriving Functor
Esto generará (en GHC 8.2)
instance Functor Queue where
fmap ...
x <$ Empty = Empty
x <$ Single y = Single x
x <$ Deep pr m sf = Deep (x <$ pr) (fmap (x <$) m) (x <$ sf)
Es posible escribir ese último caso mucho mejor a mano:
x <$ Deep pr m sf = Deep (x <$ pr) (Pair x x <$ m) (x <$ sf)
Puede ver el código derivado real utilizando -ddump-deriv
.
Estoy tratando de averiguar cuáles son exactamente las reglas para deriving Functor
en Haskell.
He visto publicaciones de mensajes al respecto, y he visto códigos de prueba al respecto, pero parece que no puedo encontrar documentación oficial sobre cuáles son las reglas. ¿Puede alguien aclararme y / o señalarme el lugar correcto?
Para utilizar el deriving Functor
, debe habilitar el lenguaje DeriveFunctor
del DeriveFunctor
y aplicarlo a un tipo polimórfico que tenga una variable de tipo final covariante, en otras palabras, un tipo que admita una instancia de Functor
válida. Entonces derivará la instancia "obvia" de Functor
.
Ha habido cierta preocupación en el pasado por el hecho de que la instancia derivada no es tan eficiente como una codificada a mano, aunque parece que no puedo encontrar ese material.
El algoritmo en sí fue, por lo que pude encontrar, propuesto por primera vez por Twan Van Laarhoven en 2007 y hace un uso intensivo de la programación Haskell genérica.