Entiendo el combinador de tipo de punto fijo regular y creo que entiendo los combinadores de tipo fijo-n de orden superior, pero HFix
me elude. Podría dar un ejemplo de un conjunto de tipos de datos y sus puntos fijos (derivados manualmente) a los que puede aplicar HFix
.¿Cómo funciona `HFix` en el paquete multirres de Haskell?
Respuesta
La referencia natural es el documento Generic programming with fixed points for mutually recursive datatypes donde se explica multirec package.
HFix
es un combinador de tipo de punto fijo para tipos de datos mutuamente recursivos. Está bien explicado en la Sección 3.2 en el papel, pero la idea es generalizar este patrón:
Fix :: (∗ -> ∗) -> ∗
Fix2 :: (∗ -> ∗ -> ∗) -> (∗ -> ∗ -> ∗) -> ∗
a
Fixn :: ((∗ ->)^n * ->)^n ∗
≈
Fixn :: (*^n -> *)^n -> *
Para restringir el número de tipos que lo hace un punto fijo sobre, se use constructores de tipo en lugar de *^n. Dan un ejemplo de un tipo de datos AST, mutuamente recursivo sobre tres tipos en el documento. Te ofrezco quizás el ejemplo más simple en su lugar. Deje nos FIXh este tipo de datos:
data Even = Zero | ESucc Odd deriving (Show,Eq)
data Odd = OSucc Even deriving (Show,Eq)
vamos a introducir el GADT familia específica para este tipo de datos como se hace en la sección 4,1
data EO :: * -> * where
E :: EO Even
O :: EO Odd
EO Even
significará que estamos llevando alrededor de un número par. Necesitamos instancias de El para que esto funcione, que indica a qué constructor específico se refiere al escribir EO Even
y EO Odd
respectivamente.
instance El EO Even where proof = E
instance El EO Odd where proof = O
Estos se utilizan como restricciones para el HFunctor
instance para I.
Definamos ahora el funtor de patrones para el tipo de datos pares e impares. Usamos los combinadores de la biblioteca.Las etiquetas constructor :>:
tipo un valor con su índice de tipos:
type PFEO = U :>: Even -- ≈ Zero ::() -> EO Even
:+: I Odd :>: Even -- ≈ ESucc :: EO Odd -> EO Even
:+: I Even :>: Odd -- ≈ OSucc :: EO Even -> EO Odd
Ahora podemos usar HFix
para atar el nudo alrededor de este patrón funtor:
type Even' = HFix PFEO Even
type Odd' = HFix PFEO Odd
Estos son ahora isomorfo a EO Incluso y EO impar, y podemos usar el hfrom
and hto
functions si lo hacemos una instancia de Fam
:
type instance PF EO = PFEO
instance Fam EO where
from E Zero = L (Tag U)
from E (ESucc o) = R (L (Tag (I (I0 o))))
from O (OSucc e) = R (R (Tag (I (I0 e))))
to E (L (Tag U)) = Zero
to E (R (L (Tag (I (I0 o))))) = ESucc o
to O (R (R (Tag (I (I0 e))))) = OSucc e
Un simple pequeña prueba:
test :: Even'
test = hfrom E (ESucc (OSucc Zero))
test' :: Even
test' = hto E test
*HFix> test'
ESucc (OSucc Zero)
Otra prueba tonto con un álgebra girando Even
y Odd
s Int
a su valor:
newtype Const a b = Const { unConst :: a }
valueAlg :: Algebra EO (Const Int)
valueAlg _ = tag (\U -> Const 0)
& tag (\(I (Const x)) -> Const (succ x))
& tag (\(I (Const x)) -> Const (succ x))
value :: Even -> Int
value = unConst . fold valueAlg E
- 1. ¿Cómo funciona el paquete?
- 2. ¿Cómo funciona el manejo de excepciones Haskell?
- 3. Haskell: ¿Cómo funciona TVar?
- 4. ¿Cómo funciona el paquete de restricciones?
- 5. Qué paquete Haskell contiene el módulo dado
- 6. autorreferencia en Haskell funciona
- 7. ¿Cómo funciona la derivación en Haskell?
- 8. ¿Cómo funciona Type Deduction en Haskell?
- 9. ¿Cómo funciona la recursividad de Haskell tail?
- 10. ¿Cómo verificar las versiones del paquete haskell en ./configure?
- 11. ¿Cómo funciona la palabra clave haskell rec?
- 12. ¿Cómo funciona la actualización del paquete OSGi?
- 13. Haskell - fmap fmap no funciona
- 14. ¿Algún paquete de álgebra lineal dispersa en Haskell?
- 15. ¿Cómo se anulan las instancias de clase de tipo Haskell proporcionadas por el código del paquete?
- 16. ¿De qué versiones de paquetes puede depender mi paquete Haskell?
- 17. Paquete de rieles: ¿cómo deshacer paquete paquete?
- 18. ¿Cómo depurar el código de Haskell?
- 19. Desesperado: Cómo instalar el paquete gráfico Haskell School of Expression, Windows XP y 7
- 20. ¿Cómo funciona el bundler (en general)?
- 21. Haskell csv-conducto en GHCi
- 22. Haskell Cabal: "paquete depende indirectamente de varias versiones del mismo paquete"
- 23. ¿Cómo y por qué funciona la mónada Haskell Cont?
- 24. ¿Cómo funciona este Haskell para calcular permutaciones utilizando el trabajo de comprensión de listas?
- 25. Haskell Pattern Matching en cadenas - ¿Por qué esto no funciona?
- 26. Cómo poner una vista en el paquete
- 27. cómo añadir una gema en el paquete
- 28. Autocompletado de Haskell en Emacs usando el modo haskell
- 29. Cómo importar el paquete java.nio.file
- 30. ¿Cómo escribo el nombre calificado de un símbolo en Haskell?
Gracias, leyendo esto ha ayudado, pero todavía estoy un poco confuso. ¿Te importaría entrar en más detalles sobre ':>:', aún me parece bastante opaco. –
Sí, es una biblioteca bastante complicada. Agregué un pequeño comentario al respecto, no tengo más tiempo en este momento. ¡Aclamaciones! – danr
Tardó un poco, pero después de leer y volver a leer esto, los documentos API y el documento, finalmente está empezando a tener sentido. Muchas gracias, has ayudado mucho. –