yoast sitename sitedesc sep page excerpt description currentyear haskell types

haskell - sitename - ¿Qué sucede con las variables de tipo faltantes en el núcleo de estilo de la Iglesia?



yoast short description (2)

Aquí está el núcleo generado por GHC (después de agregar algunos NOINLINE NOINLINE).

qoo_rbu :: forall a_abz. (a_abz -> a_abz) -> GHC.Base.String [GblId, Arity=1, Caf=NoCafRefs] qoo_rbu = / (@ a_abN) _ -> GHC.Types.[] @ GHC.Types.Char poo_rbs :: forall a_abA. GHC.Base.String -> a_abA -> a_abA [GblId, Arity=1] poo_rbs = / (@ a_abP) _ -> GHC.Base.id @ a_abP roo_rbw :: GHC.Base.String -> GHC.Base.String [GblId] roo_rbw = GHC.Base.. @ (GHC.Prim.Any -> GHC.Prim.Any) @ GHC.Base.String @ GHC.Base.String (qoo_rbu @ GHC.Prim.Any) (poo_rbs @ GHC.Prim.Any)

Parece que GHC.Prim.Any se utiliza para el tipo polimórfico.

De los documentos (énfasis mío):

El constructor de tipos Any es un tipo al que puede obligar de forma poco segura cualquier tipo levantado, y viceversa.

  • Es levantado, y por lo tanto representado por un puntero.
  • No pretende ser un tipo de datos, y eso es importante para el generador de código, ya que el código gen puede ingresar un valor de datos pero nunca ingresa un valor de función.

También se usa para instanciar variables de tipo sin restricciones después de la verificación de tipos.

Tiene sentido tener un tipo de este tipo para insertar en lugar de tipos sin restricciones, ya que de lo contrario las expresiones triviales como la length [] podrían causar un error de tipo ambiguo.

Esto es un poco esotérico, pero enloquecedor. En respuesta a otra pregunta , noté que en este programa completamente válido

poo :: String -> a -> a poo _ = id qoo :: (a -> a) -> String qoo _ = "" roo :: String -> String roo = qoo . poo

La variable de tipo a no se resuelve ni se generaliza en el proceso de verificación de roo . Me pregunto qué pasará con la traducción al lenguaje central de GHC, una variante del Sistema F al estilo de la Iglesia. Permítanme explicar las cosas a mano, con el tipo explícito lambdas // y aplicaciones de tipo @ .

poo :: forall a. [Char] -> a -> a poo = // a -> / s x -> id @ a qoo :: forall a. (a -> a) -> [Char] qoo = // a -> / f -> [] @ Char roo :: [Char] -> [Char] roo = (.) @ [Char] @ (? -> ?) @ [Char] (qoo @ ?) (poo @ ?)

¿Qué diablos pasa en el ? lugares ¿Cómo se convierte roo en un término central válido? ¿O realmente obtenemos un misterioso cuantificador de vacío, a pesar de lo que dice la firma de tipo?

roo :: forall a. [Char] -> [Char] roo = // a -> ...

Acabo de comprobar que

roo :: forall . String -> String roo = qoo . poo

pasa por ok, lo que puede significar o no que la cosa se compruebe sin cuantificación adicional.

¿Qué está pasando ahí abajo?


Esto no es un problema. En la firma de roo , la variable de tipo a simplemente no aparece como está. Un ejemplo más fácil sería la expresión.

const 1 id

dónde

id :: forall a.a->a