Closed RyanGlScott closed 4 months ago
A similar bug exists when reifying a locally defined data constructor:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TemplateHaskell #-}
module Bug where
import Data.Kind (Type)
import Language.Haskell.TH hiding (Type)
import Language.Haskell.TH.Desugar
$(do decs <- [d| type P :: forall {k}. k -> Type
data P (a :: k) = MkP |]
DataConI _ pTy _ <- withLocalDeclarations decs $ reifyWithLocals $ mkName "MkP"
runIO $ putStrLn $ pprint pTy
pure [])
[1 of 1] Compiling Bug ( Bug.hs, interpreted )
forall k_0 (a_1 :: k_0) . P_2 a_1
Again, k_0
should be inferred, not specified.
See also #220, which is in similar territory.
In this example:
The type of
MkP
, as reported by GHCi's:type
command, is:But this is not the same type that is given to
MkP
after round-tripping throughth-desugar
:Here,
k
is specified rather than inferred! What went wrong?In some sense, the problem lies with
reify
. If you replacedecToTH ddec
withdec
above, then it reveals whatreify ''P
returns:If this is to be believed, then
P
was declared asdata P (a :: k) = MkP
, which would suggest thatk
is indeed specified. We know this not to be the case, of course. And indeed, thisreify
quirk is a deliberate design choice: see the discussion at GHC#22828 for more details.One way to solve this problem would be to call
reifyType 'MkP
, which tells us:This preserves the fact that
k
is inferred. We could use the output ofreifyType
as a guide when determining whether type variables in a Haskell98-style data constructor are specified or inferred.