2011-12-31 5 views
8

Lo siguiente no se compila:declaraciones de datos de plantilla que se derivan de Haskell Mostrar

import Language.Haskell.TH 
makeAlpha n = [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |] 

no puedo distinguir lo que significa en absoluto el error:

Can't derive instances where the instance context mentions 
type variables that are not data type parameters 
    Offending constraint: Show t_d 
When deriving the instance for (Show Alpha) 
In the Template Haskell quotation 
    [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |] 
In the expression: 
    [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |] 

¿Es posible hacer derivaciones ¿Me gusta esto?

+0

Creo que el problema podría ser que está tratando de derivar las instancias antes de obtener * n *; es decir, está tratando de expandir su empalme para contener las instancias, pero no puede, porque no sabe a qué se parece '$ (conT n)'. No estoy seguro, sin embargo. – ehird

+0

Pensé de manera similar, pero a menudo no puedo estar seguro de lo que está permitido y no con Template Haskell ... En este escenario, creo que es obvio que todavía no puede derivar las instancias y debe esperar el uso de la función para expandir . ¿Es esto un error? – Ana

+0

Hmm, espera, ¿no debería ser 'datos Alpha = $ (conT n)' o algo así? Creo que lo que tienes ahora es un error de tipo, al menos al echar un vistazo a [la definición de 'Dec'] (http://hackage.haskell.org/packages/archive/template-haskell/2.6.0.0/doc/html /Language-Haskell-TH-Syntax.html#t:Dec). – ehird

Respuesta

7

Este problema se debe a que las comillas TH se comprueban cuando se compilan, con empalmes reemplazados por variables. Esta suele ser una buena idea, ya que permite detectar muchos tipos de problemas antes de ejecutar el empalme, pero en algunos casos esto puede hacer que el compilador rechace erróneamente un empalme que generaría un código válido.

En este caso, esto significa que el compilador intenta comprobar este código:

data Alpha = Alpha t deriving (Show, Read) 

Esto no funciona porque los derivados Show y Read casos necesitan utilizar Show y Read para t, pero desde t no es un parámetro de tipo Alpha, no puede agregar las restricciones necesarias. Por supuesto, cuando se ejecuta este empalme, t se reemplaza por un tipo concreto, por lo que las instancias apropiadas estarán disponibles sin la necesidad de ninguna restricción, por lo que este es uno de los casos en que el compilador está siendo demasiado cauteloso.

La solución alternativa es no utilizar las comillas, sino utilizar combinadores TH, que no están sujetos a estos controles adicionales. Es complicado, pero funciona:

Ha habido some talk about relaxing the checks done on quotes, pero por ahora sólo tendrá que tratar con él.

Cuestiones relacionadas