`LPat` should be separate data type
I was really confused in !1851 (closed) when I suddenly got breakage due to XPat
s occurring after realising that type LPat = Pat
and that I could just remove all unLoc
calls on LPat
s 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 XPat
in Loc p
only, by defining XXPat
in the appropraite way? Similarly, disallow every other constructor by defining Loc p
for XVarPat
to 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