Modèle Haskell :Erreur d'étape
-
20-12-2019 - |
Question
J'essaie de comprendre comment le Quasi Quoter génère des structures TH.J'essaie donc de convertir le premier exemple de Modèle de méta-programmation pour Haskell, d'un format cité aux types uniquement.
gen :: [Format] -> ExpQ -> ExpQ
gen [] x = x
gen (D:xs) x = [| \n -> $(gen xs [| $x ++ show n |]) |]
gen (S:xs) x = [| \s -> $(gen xs [| $x ++ s |]) |]
gen (L s:xs) x = gen xs [| $x ++ $(THS.lift s) |]
gen (D:xs) x
se convertirait en
gen (D:xs) x = lamE [varP $ mkName "n"]
(appE (appE (varE 'gen) (varE 'xs))
(uInfixE (x) (varE '(Prelude.++))
(appE (varE 'Prelude.show) (varE $ mkName "n"))))
Cependant, ce fragment ne compilera pas la référence à 'xs
.
GHC crache l'erreur suivante :
src/Print/Default.hs:28:51:
Stage error: the non-top-level quoted name 'xs
must be used at the same stage at which is is bound
In the Template Haskell quotation 'xs
In the first argument of `varE', namely 'xs
In the second argument of `appE', namely `(varE 'xs)'
Existe-t-il un autre moyen de référencer le nom d'un paramètre de fonction pour que Template Haskell puisse l'utiliser ?
La solution
user2407038 a raison de dire que la traduction est désactivée.Voici une traduction plus correcte :
gen (D:xs) x = lamE [varP (mkName "n")] $
gen xs $
varE '(++)
`appE` x
`appE` (varE 'show `appE` varE (mkName "n"))
Vous ne faites pas référence au nom de xs
ou gen
ici:vous appelez simplement la fonction de manière récursive pour générer un peu plus d'AST.Cela maintient tout au même stade.