Méthode préférée d’affichage du code généré par Template Haskell

Comme vous le savez, Template Haskell est utilisé pour générer divers types d’épissures AST par programmation au moment de la compilation.

Cependant, une épissure peut souvent être très opaque et il est souvent difficile de discerner ce que génère réellement une épissure. Si vous exécutez la monade Q pour une épissure et que l’épissure est bien typée, vous obtenez une représentation show de la partie générée d’AST, mais cette représentation peut être très difficile à comprendre en raison de sa structure non structurée.

Quelle est la méthode préférée pour convertir un fragment AST généré par TH en quelque chose qui s’apparente au code Haskell normal, de sorte que le code puisse être facilement lu et compris? Peut-on reconstruire le code source, par exemple une valeur Dec donnée? Faut-il lire le code GHC Core? Y a-t-il un moyen de structurer au moins l’AST de manière à ce qu’il devienne plus lisible (au-delà de ce que fait par exemple le paquetage pretty-show )?

    Vous pouvez peut-être utiliser pprint ou ppr partir de Language.Haskell.TH.Ppr (importé automatiquement avec Language.Haskell.TH ):

     GHCi> expr <- runQ [| \fgx -> f (x*2 + 3) . g |] GHCi> putStrLn $ pprint expr \f_0 g_1 x_2 -> f_0 ((x_2 GHC.Num.* 2) GHC.Num.+ 3) GHC.Base.. g_1 

    Ce n’est pas joli, mais c’est valide Haskell. Vous devriez être en mesure de rendre la sortie plus agréable en supprimant les préfixes de module des noms Prelude (même si vous devez faire attention à ne supprimer que le préfixe attendu; Foo.* Est un opérateur infixe parfaitement valide).

    Cherchez-vous le drapeau -ddump-splices au compilateur?

    En complément de la réponse ehird :

    Notez que l’utilisation de runQ directement à partir de GHCi en général pourrait ne pas fonctionner (par exemple: les générateurs TH qui utilisent des opérations reify , voir les commentaires au-dessus de la déclaration runQ ).

    En cas d’échec, vous pouvez pprint (ou show ), transformer l’intro d’une chaîne de caractères ssortingngE puis épisser en argument pour putStrLn :

     > putStrLn $(ssortingngE . pprint =<< [| \fgx -> f (x*2 + 3) . g |]) \f_0 g_1 x_2 -> f_0 ((x_2 GHC.Num.* 2) GHC.Num.+ 3) GHC.Base.. g_1