Consider desugaring TemplateHaskell Quotes between Tc and HsToCore
Motivation
GHC currently dedicates 3000 lines to desugaring type-checked quotes directly to CoreExpr
s building the quoted AST using wired-in identifiers in Language.Haskell.TH.Lib (in GHC.HsToCore.Quote).
For example, looking at repLiteral
, the general style seems to be to (1) turn an Int
literal into an Integer
, (2) desugar this literal to Core, (3) generate Core that calls the wired-in integerL
. Wow, this is complicated!
Proposal
I read the companion paper to Oleg Kiselyov's OCaml 2023 workshop talk.
There he describes a translation scheme for (typed, but untyped should work as well) quotes in terms of simple, wired-in combinator functions such as mkLam :: Quote m => String -> (m Exp -> m Exp) -> m Exp
and lift :: Quote m => a -> m Exp
.
Following this work, I think it would be worthwhile to desugar the following user-written eta
function as follows:
eta :: Quote m => (m Exp -> m Exp) -> m Exp
eta f = [| \x -> $(f [| x |]) |]
==>
eta f = mkLam "x" (\(x :: m Exp) -> f x)
where mkLam
is defined in TH.Lib (or perhaps at some hidden, internal place of our choosing) and defined as
mkLam :: Quote m => String -> (m Exp -> m Exp) -> m Exp
mkLam s f = do n <- newName s; lam (varP n) (f (varE n))
And a literal, variable, etc. quote would desugar using lift
:
q = [| 42 |]
===>
q = lift (42 :: Integer)
Small caveat: This would require us to infer the type of the literal, but perhaps we can just default.
The idea is to move as much glue code from HsToCore.Quote into non-exposed, perhaps inlined combinators inside ghc-internal
.