Skip to content

TH pretty-printer prints GADT data family instantance declarations with invalid layout

Summary

Function Language.Haskell.TH.Ppr.pprint does a good job of pretty-printing GADT declarations when they're at the top level of a module. Unfortunately it seems to use the same layout for data instance declarations even when they're not at the top level but nested as a child of a instance declaration. It can print invalid layout in this situation.

Steps to reproduce

$ ghci -XGADTs -XTypeFamilies -XTemplateHaskell
GHCi, version 9.6.2: https://www.haskell.org/ghc/  :? for help
ghci> Language.Haskell.TH.runQ [d|class C a where {data D a; f :: a -> D a}; instance C Int where {data D a where {C1 :: C Int; C2 :: C Int}; f = C1}|] >>= putStrLn . Language.Haskell.TH.Ppr.pprint
class C_0 a_1
    where {data D_2 a_1; f_3 :: a_1 -> D_2 a_1}
instance C_0 GHC.Types.Int
    where {data D_2 a_4 where
               C1_5 :: C_0 GHC.Types.Int
               C2_6 :: C_0 GHC.Types.Int;
           f_3 = C1_5}

The printed declaration is invalid:

Output.hs:12:12: error: [GHC-58481]
    parse error on input ‘f_3’
   |
12 |            f_3 = C1_5}

Expected behavior

The easiest solution would probably be to not rely on the layout for data instance declarations, at least not when they're nested:

instance C_0 GHC.Types.Int
    where {data D_2 a_4 where {
               C1_5 :: C_0 GHC.Types.Int;
               C2_6 :: C_0 GHC.Types.Int};
           f_3 = C1_5}

Environment

  • GHC version used: 9.6.2

Optional:

  • Operating System: Fedora Linux
  • System Architecture: x86_64
Edited by Mario
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information