goldfirere / th-desugar

Desugars Template Haskell abstract syntax to a simpler format without changing semantics

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`extractBoundNamesDPat` should not extract type variables

RyanGlScott opened this issue · comments

Currently, the extractBoundNamesDPat function has a rather strange implementation:

-- | Extract the term variables bound by a 'DPat'.
--
-- This does /not/ extract any type variables bound by pattern signatures.
extractBoundNamesDPat :: DPat -> OSet Name
extractBoundNamesDPat = go
where
go :: DPat -> OSet Name
go (DLitP _) = OS.empty
go (DVarP n) = OS.singleton n
go (DConP _ tys pats) = foldMap fvDType tys <> foldMap go pats
go (DTildeP p) = go p
go (DBangP p) = go p
go (DSigP p _) = go p
go DWildP = OS.empty

The Haddocks state that it does not extract any type variables bound by pattern signatures (DSigP), which is fairly reasonable: the primary use case for extractBoundNamesDPat is to extract term-level variables. On the other hand, extractBoundNamesDPat does extract the type variables from DConPs! This feels strangely inconsistent: why would it extract type variables from DConP but not DSigP?

I believe that extractBoundNamesDPat shouldn't extract type variables from DConP either. One reason is that there is a corresponding function over Pats called extractBoundNamesPat, and this does not extract type variables from ConP or SigP.

The other reason is that extractBoundNamesDPat's only use site is in flattenDValD, which turns all bound variables in a pattern binding into let-bound definitions. This would imply that something like Just @a y = Just @Bool True would be turned into something like:

x = let a = Bool
        y = True
    in Just @a y

But this is not going to work, as GHC doesn't currently permit things like let a = Bool. Moreover, the whole premise is flawed, since GHC won't let you bind type variables in pattern bindings in the first place:

λ> Just @a y = Just @Bool True

<interactive>:3:1: error:
    • Binding type variables is not allowed in pattern bindings
    • In the pattern: Just @a y
      In a pattern binding: Just @a y = Just @Bool True

As such, I can't see any reason why we'd want to support extracting type variables in extractBoundNamesDPat. It's likely not causing any harm today, but GHC 9.10 will introduce TypeP, another form of pattern that binds type variables, and we will need to figure out how extractBoundNamesDPat should handle that. For the sake of being consistent across the board, I think extractBoundNamesDPat should not extract type variables in ConP, SigP, or TypeP.