thdesugar
Functions to desugar Template Haskell
https://github.com/goldfirere/thdesugar
Version on this page:  1.9 
LTS Haskell 22.12:  1.15@rev:1 
Stackage Nightly 20240301:  1.16 
Latest on Hackage:  1.16 
thdesugar1.9@sha256:ee54b5b0702b7817636350f1b0c0f48db1bd622737a81b2250c5bdf9ea745654,3228
Module documentation for 1.9
 Language
thdesugar
Package
This package provides the Language.Haskell.TH.Desugar
module, which desugars
Template Haskell’s rich encoding of Haskell syntax into a simpler encoding.
This desugaring discards surface syntax information (such as the use of infix
operators) but retains the original meaning of the TH code. The intended use
of this package is as a preprocessor for more advanced code manipulation
tools. Note that the input to any of the ds...
functions should be produced
from a TH quote, using the syntax [ ... ]
. If the input to these functions
is a handcoded TH syntax tree, the results may be unpredictable. In
particular, it is likely that promoted datatypes will not work as expected.
One explicit goal of this package is to reduce the burden of supporting multiple GHC / TH versions. Thus, the desugared language is the same across all GHC versions, and any inconsistencies are handled internally.
The package was designed for use with the singletons
package, so some design
decisions are based on that use case, when more than one design choice was
possible.
I will try to keep this package uptodate with respect to changes in GHC.
Changes
thdesugar
release notes
Version 1.9

Suppose GHC 8.6.

Add support for
DerivingVia
. Correspondingly, there is now aDDerivStrategy
data type. 
Add support for
QuantifiedConstraints
. Correspondingly, there is now aDForallPr
constructor inDPred
to represent quantified constraint types. 
Remove the
DStarT
constructor ofDType
in favor ofDConT ''Type
. Two utility functions have been added toLanguage.Haskell.TH.Desugar
to ease this transition:isTypeKindName
: returnsTrue
if the argumentName
is that ofType
or★
(or*
, to support older GHCs).typeKindName
: the name ofType
(on GHC 8.0 or later) or*
(on older GHCs).

thdesugar
now desugars all data types to GADT syntax. The most significant APIfacing changes resulting from this new design are:
The
DDataD
,DDataFamilyD
, andDDataFamInstD
constructors ofDDec
now haveMaybe DKind
fields that either haveJust
an explicit return kind (e.g., thek > Type > Type
indata Foo :: k > Type > Type
) orNothing
(if lacking an explicit return kind). 
The
DCon
constructor previously had a field of typeMaybe DType
, since there was a possibility it could be a GADT (with an explicit return type) or nonGADT (without an explicit return type) constructor. Since all data types are desugared to GADTs now, this field has been changed to be simply aDType
. 
The type signature of
dsCon
was previously:dsCon :: DsMonad q => Con > q [DCon]
However, desugaring constructors now needs more information than before, since GADT constructors have richer type signatures. Accordingly, the type of
dsCon
is now:dsCon :: DsMonad q => [DTyVarBndr]  ^ The universally quantified type variables  (used if desugaring a nonGADT constructor) > DType  ^ The original data declaration's type  (used if desugaring a nonGADT constructor). > Con > q [DCon]
The
instance Desugar [Con] [DCon]
has also been removed, as the previous implementation ofdesugar
(concatMapM dsCon
) no longer has enough information to work.
Some other utility functions have also been added as part of this change:

A
conExistentialTvbs
function has been introduced to determine the existentially quantified type variables of aDCon
. Note that this function is not 100% accurate—refer to the documentation forconExistentialTvbs
for more information. 
A
mkExtraDKindBinders
function has been introduced to turn a data type’s return kind into explicit, fresh type variable binders. 
A
toposortTyVarsOf
function, which finds the free variables of a list ofDType
s and returns them in a well scoped list that has been sorted in reverse topological order.


thdesugar
now desugars partial pattern matches indo
notation and list/monad comprehensions to the appropriate invocation offail
. (Previously, these were incorrectly desugared intocase
expressions with incomplete patterns.) 
Add a
mkDLamEFromDPats
function for constructing aDLamE
expression using a list ofDPat
arguments and aDExp
body. 
Add an
unravel
function for decomposing a function type into itsforall
’d type variables, its context, its argument types, and its result type. 
Export a
substTyVarBndrs
function fromLanguage.Haskell.TH.Desugar.Subst
, which substitutes over type variable binders in a captureavoiding fashion. 
getDataD
,dataConNameToDataName
, anddataConNameToCon
fromLanguage.Haskell.TH.Desugar.Reify
now look up local declarations. As a result, the contexts in their type signatures have been strengthened fromQuasi
toDsMonad
. 
Export a
dTyVarBndrToDType
function which converts aDTyVarBndr
to aDType
, which preserves its kind. 
Previously,
thdesugar
would silently accept illegal uses of record construction with fields that did not belong to the constructor, such asIdentity { notAField = "wat" }
. This is now an error.
Version 1.8

Support GHC 8.4.

substTy
now properly substitutes into kind signatures. 
Expose
fvDType
, which computes the free variables of aDType
. 
Incorporate a
DDeclaredInfix
field intoDNormalC
to indicate if it is a constructor that was declared infix. 
Implement
lookupValueNameWithLocals
,lookupTypeNameWithLocals
,mkDataNameWithLocals
, andmkTypeNameWithLocals
, counterparts tolookupValueName
,lookupTypeName
,mkDataName
, andmkTypeName
which have access to local Template Haskell declarations. 
Implement
reifyNameSpace
to determine aName
’sNameSpace
. 
Export
reifyFixityWithLocals
fromLanguage.Haskell.TH.Desugar
. 
Export
matchTy
(among other goodies) from new moduleLanguage.Haskell.TH.Subst
. This function matches a type template against a target.
Version 1.7

Support for TH’s support for
TypeApplications
, thanks to @RyanGlScott. 
Support for unboxed sums, thanks to @RyanGlScott.

Support for
COMPLETE
pragmas. 
getRecordSelectors
now requires a list ofDCon
s as an argument. This makes it easier to return correct record selector bindings in the event that a record selector appears in multiple constructors. (See goldfirere/singletons#180 for an example of where the old behavior ofgetRecordSelectors
went wrong.) 
Better type family expansion (expanding an open type family with variables works now).
Version 1.6

Work with GHC 8, with thanks to @christiaanb for getting this change going. This means that several core datatypes have changed: partcularly, we now have
DTypeFamilyHead
and fixities are now reified separately from other things. 
DKind
is merged withDType
. 
Generic
instances for everything.
Version 1.5.5
 Fix issue #34. This means that desugaring (twice) is idempotent over expressions, after the second time. That is, if you desugar an expression, sweeten it, desugar again, sweeten again, and then desugar a third time, you get the same result as when you desugared the second time. (The extra roundtrip is necessary there to make the output smaller in certain common cases.)
Version 1.5.4.1
 Fix issue #32, concerning reification of classes with default methods.
Version 1.5.4
 Added
expandUnsoundly
Version 1.5.3
 More
DsMonad
instances, thanks to David Fox.
Version 1.5.2
 Sweeten kinds more, too.
Version 1.5.1

Thanks to David Fox (@ddssff), sweetening now tries to use more of TH’s
Type
constructors. 
Also thanks to David Fox, depend usefully on the thorphans package.
Version 1.5

There is now a facility to register a list of
Dec
that internal reification should use when necessary. This avoids the user needing to break up their definition across different toplevel splices. SeewithLocalDeclarations
. This has a side effect of changing theQuasi
typeclass constraint on many functions to be the newDsMonad
constraint. Happily, there areDsMonad
instances forQ
andIO
, the two normal inhabitants ofQuasi
. 
“Match flattening” is implemented! The functions
scExp
andscLetDec
remove any nested pattern matches. 
More is now exported from
Language.Haskell.TH.Desugar
for ease of use. 
expand
can now expand closed type families! It still requires that the type to expand contain no type variables. 
Support for standalonederiving and default signatures in GHC 7.10. This means that there are now two new constructors for
DDec
. 
Support for
static
expressions, which are new in GHC 7.10.
Version 1.4.2
expand
functions now consider open type families, as long as the type to be expanded has no free variables.
Version 1.4.1

Added
Language.Haskell.TH.Desugar.Lift
, which providesLift
instances for all of the thdesugar types, as well as several Template Haskell types. 
Added
applyDExp
andapplyDType
as convenience functions.
Version 1.4.0

All
Dec
s can now be desugared, to the newDDec
type. 
Sweetening
Dec
s that do not exist in GHC 7.6.3 works on a “best effort” basis: closed type families are sweetened to open ones, and role annotations are dropped. 
Info
s can now be desugared. Desugaring takes into account GHC bug #8884, which meant that reifying polykinded type families in GHC 7.6.3 was subtly wrong. 
There is a new function
flattenDValD
which takes a binding likelet (a,b) = foo
and breaks it apart into separate assignments fora
andb
. 
There is a new
Desugar
class with methodsdesugar
andsweeten
. See the documentation inLanguage.Haskell.TH.Desugar
. 
Variable names that are distinct in desugared code are now guaranteed to have distinct answers to
nameBase
. 
Added a new function
getRecordSelectors
that extracts types and definitions of record selectors from a datatype definition.
Version 1.3.1
 Update cabal file to include testing files in sdist.
Version 1.3.0
 Update to work with
type Pred = Type
in GHC 7.9. This changed theDPred
type for all GHC versions, though.
Version 1.2.0
 Generalized interface to allow any member of the
Qausi
class, instead of justQ
.
Version 1.1.1
 Made compatible with HEAD after change in role annotation syntax.
Version 1.1
 Added module
Language.Haskell.TH.Desugar.Expand
, which allows for expansion of type synonyms in desugared types.  Added
Show
,Typeable
, andData
instances to desugared types.  Fixed bug where an aspattern in a
let
statement was scoped incorrectly.  Changed signature of
dsPat
to be more specific to aspatterns; this allowed for fixing thelet
scoping bug.  Created new functions
dsPatOverExp
anddsPatsOverExp
to allow for easy desugaring of patterns.  Changed signature of
dsLetDec
to return a list ofDLetDec
s.  Added
dsLetDecs
for convenience. Now, instead of usingmapM dsLetDec
, you should usedsLetDecs
.
Version 1.0
 Initial release