`LPat` should be separate data type
I was really confused in !1851 (closed) when I suddenly got breakage due to
XPats occurring after realising that
type LPat = Pat and that I could just remove all
unLoc calls on
LPats without the type checker complaining. I don't think this is a satisfying solution at all.
I really liked the type safety of the old "ping-pong" approach.
So why don't we define
data LPat p = LPat (XLPat p) (Pat p)? That additional indirection is probably too inefficient for TH. Also we could just have
data Located p r = L (XL p) r as a generalisation, which shares all the same problems.
Why don't we define
newtype LPat p = LPat (Loc p) (we don't even need the newtype) and allow
Loc p only, by defining
XXPat in the appropraite way? Similarly, disallow every other constructor by defining
Loc p for
noExtCon, so that we can't instantiate it. No overhead at all, still all the type safety. Arguably more complex.
Less prose, more pseudo-code:
data Loc p type LPat p = Pat (Loc p) type instance XVarPat (Loc (GhcPass p)) = NoExtCon -- case in point, or just omit it ... type instance XXPat (Loc (GhcPass p)) = Located (Pat (GhcPass p)) -- as previously data Pat p = VarPat (XVarPat p) ... | ... | SigPat (XSigPat p) (LPat p) (LHsSigWcType (NoGhcTc p)) | .. | XPat (XXPat p) type instance XVarPat (GhcPass p) = NoExtField -- as previously ... type instance XXPat (GhcPass p) = NoExtCon -- case in point, or just omit it