Opened 16 months ago

Last modified 5 days ago

#11785 patch task

Merge types and kinds in Template Haskell

Reported by: goldfire Owned by:
Priority: normal Milestone:
Component: Template Haskell Version: 8.1
Keywords: TypeInType Cc: RyanGlScott
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s): Phab:D3751
Wiki Page:


TcSplice handles kinds differently than types. Now that they are the same, it's probably best to rewrite this code.

Change History (5)

comment:1 Changed 16 months ago by RyanGlScott

Cc: RyanGlScott added

comment:2 Changed 7 weeks ago by RyanGlScott

Another place we should unify the treatment of Types and Kinds is DsMeta. We have both repLTy and repLKind, but the latter covers far fewer things than the former, which has led to bugs like #13781.

Sadly, accomplishing this requires more work than you'd believe, since repLTy returns a TypeQ, whereas repLKind returns a pure Kind. In other words, we'd have to go through and purify repLTy, as well as every function it calls which is also monadic (see

comment:3 Changed 7 weeks ago by goldfire

Keywords: TypeInType added

comment:4 Changed 6 days ago by RyanGlScott

Summary: Kinds should be treated like types in TcSpliceMerge types and kinds in Template Haskell

Actually, there's another way to go about this. Instead of making more things pure, we could make more things monadic. This can be accomplished with the following combinator:

bindCore :: DsM (Core (TH.Q a)) -> (Core a -> DsM (Core (TH.Q b)))
         -> DsM (Core (TH.Q b))
bindCore dsma f
  = do { cqa@(MkC qa) <- dsma
       ; loc <- getSrcSpanDs
       ; a_name <- newNameAt (mkVarOccFS (fsLit "a")) loc
       ; let [a_ty] = tcTyConAppArgs (exprType qa)
       ; let a_id = mkLocalId (localiseName a_name) a_ty
             ca   = MkC (Var a_id)
       ; MkC qb <- f ca
       ; let [b_ty] = tcTyConAppArgs (exprType qb)
       ; repBindQ a_ty b_ty cqa (MkC (Lam a_id qb)) }

With bindCore, we can retrofit existing uses of repLKind with repLTy. Here's one example:

  • compiler/deSugar/DsMeta.hs

    diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs
    index c679981..8acc6eb 100644
    a b repTy (HsEqTy t1 t2) = do 
    10431044                         repTapps eq [t1', t2']
    10441045repTy (HsKindSig t k)       = do
    10451046                                t1 <- repLTy t
    1046                                 k1 <- repLKind k
    1047                                 repTSig t1 k1
     1047                                bindCore (repLTy k) $ repTSig t1
     1048                                -- k1 <- repLKind k
     1049                                -- repTSig t1 k1
    10481050repTy (HsSpliceTy splice _)     = repSplice splice
    10491051repTy (HsExplicitListTy _ _ tys) = do
    10501052                                    tys1 <- repLTys tys

It's somewhat unsavory, but it prevents us from having to change a truckload of combinators in Language.Haskell.TH.Lib to take KindQ as an argument instead of Kind.

comment:5 Changed 5 days ago by RyanGlScott

Differential Rev(s): Phab:D3751
Status: newpatch

Phab:D3751 addresses the DsMeta portion of this ticket.

Note: See TracTickets for help on using tickets.