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 ?

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top