2011-12-31 12 views
8

Quanto segue non può essere compilato:dichiarazioni di dati Template Haskell che derivano Visualizza

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

non riesco a capire che cosa l'errore significa affatto:

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) |] 

E 'possibile fare derivazioni come questo?

+0

Penso che il problema potrebbe essere che sta cercando di derivare le istanze prima che ottenga * n *; per esempio sta cercando di espandere la tua giunzione per contenere le istanze, ma non può, perché non sa che cosa '$ (conT n)' assomiglia. Non sono sicuro, però. – ehird

+0

Ho pensato allo stesso modo, ma spesso non posso essere sicuro di cosa sia permesso e non con Template Haskell ... In questo scenario penso sia ovvio che non possa ancora derivare le istanze e che debba attendere l'utilizzo della funzione per espandere . è un insetto? – Ana

+0

Hmm, aspetta, non dovrebbe essere 'data Alpha = $ (conT n)' o qualcosa del genere? Penso che quello che hai ora è un errore di tipo, almeno dal dare un'occhiata alla [definizione di 'Dec'] (http://hackage.haskell.org/packages/archive/template-haskell/2.6.0.0/doc/html /Language-Haskell-TH-Syntax.html#t:Dec). – ehird

risposta

7

Questo problema si verifica perché le quotazioni TH vengono controllate quando vengono compilate, con le giunzioni sostituite da variabili. Di solito, questa è una buona idea, perché consente di rilevare molti tipi di problemi prima che venga eseguita la giunzione, ma in alcuni casi ciò può impedire al compilatore di rifiutare in modo errato una giunzione che genererebbe codice valido.

In questo caso, ciò significa che il compilatore cerca di controllare questo codice:

data Alpha = Alpha t deriving (Show, Read) 

Ciò non funziona perché i derivati ​​Show e Read casi hanno bisogno di usare Show e Read per t, ma dal momento che t non è un parametro di tipo Alpha, non è possibile aggiungere i vincoli necessari. Naturalmente, quando viene eseguito questo splicing, t viene sostituito da un tipo concreto, quindi le istanze appropriate saranno disponibili senza la necessità di alcun vincolo, quindi questo è uno dei casi in cui il compilatore è troppo cauto.

La soluzione alternativa consiste nel non utilizzare le virgolette, ma utilizzare i combinatori TH, che non sono soggetti a questi controlli aggiuntivi. E 'disordinato, ma funziona:

C'è stato some talk about relaxing the checks done on quotes, ma per ora ti basta avere a che fare con esso.

Problemi correlati