Changelog History
Page 1

v1.12 Changes
 π Support GHC 9.0.
β Add support for explicit specificity. As part of this change, the way
thdesugar
represents type variable binders has been overhauled: The
DTyVarBndr
data type is now parameterized by aflag
type parameter:
data DTyVarBndr flag = DPlainTV Name flag  DKindedTV Name flag DKind
This can be instantiated to
Specificity
(for type variable binders that can be specified or inferred) or()
(for type variable binders where specificity is irrelevant).DTyVarBndrSpec
andDTyVarBndrUnit
are also provided as type synonyms forDTyVarBndr Specificity
andDTyVarBndr ()
, respectively. In order to interface with
TyVarBndr
(the TH counterpart toDTyVarBndr
) in a backwardscompatible way,thdesugar
now depends on thethabstraction
library.  The
ForallVisFlag
has been removed in favor of the newDForallTelescope
data type, which not only distinguishes between invisible and visibleforall
s but also uses the correct type variable flag for invisible type variables (Specificity
) and visible type variables (()
).  The type of the
dsTvb
is now different on pre9.0 versions of GHC:
#if __GLASGOW_HASKELL__ >= 900 dsTvb :: DsMonad q => TyVarBndr flag > q (DTyVarBndr flag) #else dsTvb :: DsMonad q => flag > TyVarBndr > q (DTyVarBndr flag) #endif
This is unfortunately required by the fact that prior to GHC 9.0, there is no
flag
information stored anywhere in aTyVarBndr
. If you need to usedsTvb
in a backwardcompatible way,L.H.TH.Desugar
now providesdsTvbSpec
anddsTvbUnit
functions which specialisedsTvb
to particularflag
types:dsTvbSpec :: DsMonad q => TyVarBndrSpec > q DTyVarBndrSpec dsTvbUnit :: DsMonad q => TyVarBndrUnit > q DTyVarBndrUnit
 The
The type of the
getRecordSelectors
function has changed:
getRecordSelectors :: DsMonad q => DType > [DCon] > q [DLetDec] +getRecordSelectors :: DsMonad q => [DCon] > q [DLetDec]
The old type signature had a
DType
argument whose sole purpose was to help determine which type variables were existential, as this information was used to filter out "naughty" record selectors, like the example below:data Some :: (Type > Type) > Type where MkSome :: { getSome :: f a } > Some f
The old implementation of
getRecordSelectors
would not includegetSome
in the returned list, as its typef a
mentions an existential type variable,a
, that is not mentioned in the return typeSome f
. The new implementation ofgetRecordSelectors
, on the other hand, makes no attempt to filter out naughty record selectors, so it would includegetSome
.This reason for this change is ultimately because determining which type variables are existentially quantified in the context of Template Haskell is rather challenging in the general case. There are heuristics we could employ to guess which variables are existential, but we have found these heuristics difficult to predict (let alone specify). As a result, we take the slightly less correct (but much easier to explain) approach of returning all record selectors, regardless of whether they are naughty or not.
 π The
conExistentialTvbs
function has been removed. It was horribly buggy, especially in the presence of GADT constructors. Moreover, this function was used in the implementation ofgetRecordSelectors
function, so bugs inconExistentialTvbs
often affected the results ofgetRecordSelectors
.  The types of
decToTH
,letDecToTH
, andpragmaToTH
have changed:
decToTH :: DDec > [Dec] +decToTH :: DDec > Dec letDecToTH :: DLetDec > Maybe Dec +letDecToTH :: DLetDec > Dec pragmaToTH :: DPragma > Maybe Pragma +pragmaToTH :: DPragma > Pragma
The semantics of
pragmaToTH
have changed accordingly. Previously,pragmaToTH
would returnNothing
when the argument is aDPragma
that is not supported on an old version of GHC, but now an error will be thrown instead.decToTH
andletDecToTH
, which transitively invokepragmaToTH
, have had their types updated to accommodatepragmaToTH
's type change. The type of the
substTyVarBndrs
function has been simplified to avoid the needless use of continuationpassing style:
substTyVarBndrs :: Quasi q => DSubst > [DTyVarBndr flag] > (DSubst > [DTyVarBndr flag] > q a) > q a +substTyVarBndrs :: Quasi q => DSubst > [DTyVarBndr flag] > q (DSubst, [DTyVarBndr flag])

v1.11 Changes
 π Support GHC 8.10.
β Add support for visible dependent quantification. As part of this change, the way
thdesugar
representsforall
and constraint types has been overhauled: The existing
DForallT
constructor has been split into two smaller constructors:
data DType = ...   DForallT [DTyVarBndr] DCxt DType +  DForallT ForallVisFlag [DTyVarBndr] DType +  DConstrainedT DCxt DType  ... +data ForallVisFlag + = ForallVis +  ForallInvis
The previous design combined
forall
s and constraints into a single constructor, while the new design puts them in distinct constructorsDForallT
andDConstrainedT
, respectively. The newDForallT
constructor also has aForallVisFlag
field to distinguish invisibleforall
s (e.g.,forall a. a
) from visibleforall
s (e.g.,forall a > a
). The
unravel
function has been renamed tounravelDType
and now returns(DFunArgs, DType)
, whereDFunArgs
is a data type that represents the possible arguments in a function type (see the Haddocks forDFunArgs
for more details). There is also anunravelDType
counterpart forType
s namedunravelType
, complete with its ownFunArgs
data type.
{D}FunArgs
also have some supporting operations, includingfilter{D}VisFunArgs
(to obtain only the visible arguments) andravel{D}Type
(to construct a function type using{D}FunArgs
and a return{D}Type
). The existing
π Support standalone kind signatures by adding a
DKiSigD
constructor toDDec
.β Add
dsReifyType
,reifyTypeWithLocals_maybe
, andreifyTypeWithLocals
, which allow looking up the types or kinds of locally declared entities.π Fix a bug in which
reifyFixityWithLocals
would not look into local fixity declarations inside of type classes.π Fix a bug in which
reifyFixityWithLocals
would return incorrect results for classes with associated type family defaults.

v1.10 Changes
 π Support GHC 8.8. Drop support for GHC 7.6.
β Add support for visible kind application, type variable
foralls
inRULES
, and explicitforall
s in type family instances. Correspondingly, There is now a
DAppKindT
constructor inDType
.  Previously, the
DDataInstD
constructor had fields of typeName
and[DType]
. Those have been scrapped in favor of a single field of typeDType
, representing the application of the data family name (which was previously theName
) to its arguments (which was previously the[DType]
).
DDataInstD
also has a new field of typeMaybe [DTyVarBndr]
to represent its explicitly quantified type variables (if present). Previously, the
DTySynEqn
constructor had a field of type[DType]
. That has been scrapped in favor of a field of typeDType
, representing the application of the type family name (whichDTySynEqn
did not used to contain!) to its arguments (which was previously the[DType]
).
DTySynEqn
also has a new field of typeMaybe [DTyVarBndr]
to represent its explicitly quantified type variables (if present).DTySynInstD
no longer has a field of typeName
, as that is redundant now that eachDTySynEqn
contains the sameName
. There is now a field of type
Maybe [DTyVarBndr]
in theDRuleP
constructor to represent bound type variables inRULES
(if present).
 There is now a
β Add a field of type
Maybe [DTyVarBndr]
toDInstanceD
andDStandaloneDerivD
for optionally quantifying type variables explicitly. If supplied with aJust
, this sweetens the instance type to use aForallT
to represent the explicit quantification. This trick is not supported forInstanceD
on GHC 8.0 and forStandaloneDerivD
on GHC 7.10 or 8.0, so be aware of this limitation if you supplyJust
for this field.β Add support for desugaring implicit params. This does not involve any changes to the
thdesugar
AST, as:(?x :: a) => ...
is desugared toIP "x" a => ...
.id ?x
is desugared toid (ip @"x")
.let ?x = 42 in ...
is desugared tolet new_x_val = 42 in bindIP @"x" new_x_val ...
(wherebindIP
is a new utility function exported byLanguage.Haskell.TH.Desugar
on GHC 8.0 or later).
In order to support this desugaring, the type signatures of
dsLetDec
anddsLetDecs
now return([DLetDec], DExp > DExp)
instead of just[DLetDec]
, whereDExp > DExp
is the expression which binds the values of implicit params (e.g.,\z > bindIP @"x" new_x_val z
) if any are bound. (If none are bound, this is simply theid
function.) π Fix a bug in which
toposortTyVarsOf
would error at runtime if given types containingforall
s as arguments.  π Fix a bug in which
fvDType
would return incorrect results if given a type containing quantified constraints.  π Fix a bug in which
expandType
would not expand type synonyms in the kinds of type variable binders inforall
s.  π Fix a bug in which
getRecordSelectors
would omit record selectors from GADT constructors.  π Fix a bug in which
toposortTyVarsOf
would sometimes not preserve the lefttoright ordering ofName
s generated withqNewName
.  Locally reified class methods, data constructors, and record selectors now quantify kind variables properly.
 Desugared ADT constructors now quantify kind variables properly.
 β Remove
DPred
, as it has become too similar toDType
. This also means that theDPat
constructors, which previously ended with the suffixPa
, can now use the suffixP
, mirroring TH.  The type of
applyDType
has changed fromDType > [DType] > DType
toDType > [DTypeArg] > DType
, whereDTypeArg
is a new data type that encodes whether an argument is a normal type argument (e.g., theInt
inMaybe Int
) or a visible kind argument (e.g., the@Type
inProxy @Type Char
). ATypeArg
data type (which is likeDTypeArg
, but withType
s/Kind
s instead ofDType
s/DKind
s) is also provided.
A handful of utility functions for manipulating
TypeArg
s andDTypeArg
s are also exported. π
thdesugar
functions that compute free variables (e.g.,fvDType
) now return anOSet
, a variant ofSet
that remembers the order in which elements were inserted. A consequence of this change is that it fixes a bug that causes free variables to be computed in different orders depending on which unique numbers GHC happened to generate internally.  Substition and type synonym expansion are now more efficient by avoiding
the use of
syb
in inner loops.

v1.9 Changes
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. The
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.

v1.8 Changes
π 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.

v1.7 Changes
π 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).

v1.6 Changes
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.

v1.5.5 Changes
 π 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.)

v1.5.4 Changes
 β Added
expandUnsoundly
 β Added

v1.5.4.1 Changes
 π Fix issue #32, concerning reification of classes with default methods.