th-desugar v1.9 Release Notes

    • Suppose GHC 8.6.

    • ➕ Add support for DerivingVia. Correspondingly, there is now a DDerivStrategy data type.

    • ➕ Add support for QuantifiedConstraints. Correspondingly, there is now a DForallPr constructor in DPred to represent quantified constraint types.

    • ✂ Remove the DStarT constructor of DType in favor of DConT ''Type. Two utility functions have been added to Language.Haskell.TH.Desugar to ease this transition:

      • isTypeKindName: returns True if the argument Name is that of Type or (or *, to support older GHCs).
      • typeKindName: the name of Type (on GHC 8.0 or later) or * (on older GHCs).
    • th-desugar now desugars all data types to GADT syntax. The most significant API-facing changes resulting from this new design are:

      • The DDataD, DDataFamilyD, and DDataFamInstD constructors of DDec now have Maybe DKind fields that either have Just an explicit return kind (e.g., the k -> Type -> Type in data Foo :: k -> Type -> Type) or Nothing (if lacking an explicit return kind).
      • The DCon constructor previously had a field of type Maybe DType, since there was a possibility it could be a GADT (with an explicit return type) or non-GADT (without an explicit return type) constructor. Since all data types are desugared to GADTs now, this field has been changed to be simply a DType.
      • 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 non-GADT constructor)
            -> DType        -- ^ The original data declaration's type
                            --   (used if desugaring a non-GADT constructor).
            -> Con -> q [DCon]
      

      The instance Desugar [Con] [DCon] has also been removed, as the previous implementation of desugar (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 a DCon. Note that this function is not 100% accurate—refer to the documentation for conExistentialTvbs 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 of DTypes and returns them in a well scoped list that has been sorted in reverse topological order.

      • th-desugar now desugars partial pattern matches in do-notation and list/monad comprehensions to the appropriate invocation of fail. (Previously, these were incorrectly desugared into case expressions with incomplete patterns.)
      • ➕ Add a mkDLamEFromDPats function for constructing a DLamE expression using a list of DPat arguments and a DExp body.
      • ➕ Add an unravel function for decomposing a function type into its forall'd type variables, its context, its argument types, and its result type.
      • Export a substTyVarBndrs function from Language.Haskell.TH.Desugar.Subst, which substitutes over type variable binders in a capture-avoiding fashion.
      • getDataD, dataConNameToDataName, and dataConNameToCon from Language.Haskell.TH.Desugar.Reify now look up local declarations. As a result, the contexts in their type signatures have been strengthened from Quasi to DsMonad.
      • Export a dTyVarBndrToDType function which converts a DTyVarBndr to a DType, which preserves its kind.
      • Previously, th-desugar would silently accept illegal uses of record construction with fields that did not belong to the constructor, such as Identity { notAField = "wat" }. This is now an error.