Skip to content

`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 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
Edited by Sebastian Graf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information