haskell functor

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.