----------------------------------------------------------------------------
-- |
-- Module : Prettyprinter.Generics
-- Copyright : (c) Sergey Vinokurov 2018
-- License : Apache-2.0 (see LICENSE)
-- Maintainer : serg.foo@gmail.com
----------------------------------------------------------------------------
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Prettyprinter.Generics
( ppGeneric
, PPGeneric(..)
, PPGenericOverride(..)
-- * Reexports
, Pretty(..)
, Generic
) where
import Data.Bimap (Bimap)
import Data.ByteString.Char8 qualified as C8
import Data.ByteString.Lazy.Char8 qualified as CL8
import Data.ByteString.Short qualified as ShortBS
import Data.DList (DList)
import Data.DList qualified as DL
#ifdef HAVE_ENUMMAPSET
import Data.EnumMap (EnumMap)
import Data.EnumSet (EnumSet)
#endif
import Data.Foldable
import Data.Functor.Compose
import Data.HashMap.Strict (HashMap)
import Data.HashSet (HashSet)
import Data.Int
import Data.IntMap (IntMap)
import Data.IntSet (IntSet)
import Data.Kind
import Data.List.NonEmpty (NonEmpty)
import Data.Map (Map)
import Data.Proxy
import Data.Set (Set)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.Lazy qualified as TL
import Data.Vector (Vector)
import Data.Void
import Data.Word
import GHC.ForeignPtr (ForeignPtr(..))
import GHC.Generics
import GHC.Real (Ratio(..))
import GHC.Stack (CallStack)
import GHC.TypeLits
import Prettyprinter
import Prettyprinter.Combinators
import Prettyprinter.MetaDoc
import Language.Haskell.TH qualified as TH
import Language.Haskell.TH.Syntax qualified as TH
-- $setup
-- >>> :set -XDeriveGeneric
-- >>> :set -XDerivingVia
-- >>> :set -XImportQualifiedPost
-- >>> import Data.List.NonEmpty (NonEmpty(..))
-- >>> import Data.List.NonEmpty qualified as NonEmpty
-- >>> import Data.IntMap (IntMap)
-- >>> import Data.IntMap qualified as IntMap
-- >>> import Data.IntSet (IntSet)
-- >>> import Data.IntSet qualified as IntSet
-- >>> import Data.Map.Strict (Map)
-- >>> import Data.Map.Strict qualified as Map
-- >>> import Data.Set (Set)
-- >>> import Data.Set qualified as Set
-- >>> import Data.Vector (Vector)
-- >>> import Data.Vector qualified as Vector
-- >>> import GHC.Generics (Generic)
--
-- >>> :{
-- data Test = Test
-- { testSet :: Maybe (Set Int)
-- , testMap :: Map String (Set Double)
-- , testIntSet :: IntSet
-- , testIntMap :: IntMap String
-- , testInt :: Int
-- , testComplexMap :: Map (Maybe (Set Int)) (IntMap (Set String))
-- , testComplexMap2 :: Map (Maybe (Set Int)) (Map (NonEmpty Int) (Vector String))
-- } deriving (Generic)
-- :}
-- | Helper to use 'GHC.Generics.Generic'-based prettyprinting with DerivingVia.
--
-- >>> :{
-- data TestWithDeriving a b = TestWithDeriving
-- { testSet :: Maybe (Set a)
-- , testB :: b
-- , testIntMap :: IntMap String
-- , testComplexMap :: Map (Maybe (Set Int)) (IntMap (Set String))
-- }
-- deriving (Generic)
-- deriving Pretty via PPGeneric (TestWithDeriving a b)
-- :}
--
newtype PPGeneric a = PPGeneric { unPPGeneric :: a }
instance (Generic a, GPretty (Rep a)) => Pretty (PPGeneric a) where
pretty = ppGeneric . unPPGeneric
-- | Prettyprint using 'GHC.Generics.Generic' instance.
--
-- >>> :{
-- test = Test
-- { testSet = Just $ Set.fromList [1..3]
-- , testMap =
-- Map.fromList [("foo", Set.fromList [1.5]), ("foo", Set.fromList [2.5, 3, 4])]
-- , testIntSet = IntSet.fromList [1, 2, 4, 5, 7]
-- , testIntMap = IntMap.fromList $ zip [1..] ["3", "2foo", "11"]
-- , testInt = 42
-- , testComplexMap = Map.fromList
-- [ ( Nothing
-- , IntMap.fromList $ zip [0..] $ map Set.fromList
-- [ ["foo", "bar"]
-- , ["baz"]
-- , ["quux", "frob"]
-- ]
-- )
-- , ( Just (Set.fromList [1])
-- , IntMap.fromList $ zip [0..] $ map Set.fromList
-- [ ["quux"]
-- , ["fizz", "buzz"]
-- ]
-- )
-- , ( Just (Set.fromList [3, 4])
-- , IntMap.fromList $ zip [0..] $ map Set.fromList
-- [ ["quux", "5"]
-- , []
-- , ["fizz", "buzz"]
-- ]
-- )
-- ]
-- , testComplexMap2 =
-- Map.singleton
-- (Just (Set.fromList [1..5]))
-- (Map.fromList
-- [ (NonEmpty.fromList [1, 2], Vector.fromList ["foo", "bar", "baz"])
-- , (NonEmpty.fromList [3], Vector.fromList ["quux"])
-- , (NonEmpty.fromList [4..10], Vector.fromList ["must", "put", "something", "in", "here"])
-- ])
-- }
-- :}
--
-- >>> ppGeneric test
-- Test
-- { testSet -> Just ({1, 2, 3})
-- , testMap -> {foo -> {2.5, 3.0, 4.0}}
-- , testIntSet -> {1, 2, 4, 5, 7}
-- , testIntMap -> {1 -> 3, 2 -> 2foo, 3 -> 11}
-- , testInt -> 42
-- , testComplexMap ->
-- { Nothing -> {0 -> {bar, foo}, 1 -> {baz}, 2 -> {frob, quux}}
-- , Just ({1}) -> {0 -> {quux}, 1 -> {buzz, fizz}}
-- , Just ({3, 4}) -> {0 -> {5, quux}, 1 -> {}, 2 -> {buzz, fizz}}
-- }
-- , testComplexMap2 ->
-- { Just ({1, 2, 3, 4, 5}) ->
-- { [1, 2] -> [foo, bar, baz]
-- , [3] -> [quux]
-- , [4, 5, 6, 7, 8, 9, 10] -> [must, put, something, in, here]
-- } }
-- }
ppGeneric :: (Generic a, GPretty (Rep a)) => a -> Doc ann
ppGeneric = mdPayload . gpretty . from
class GPretty (a :: Type -> Type) where
gpretty :: a ix -> MetaDoc ann
instance GPretty V1 where
gpretty _ = error "gpretty for V1"
instance GPretty U1 where
gpretty U1 = mempty
instance (GPretty f, GPretty g) => GPretty (f :+: g) where
gpretty = \case
L1 x -> gpretty x
R1 y -> gpretty y
-- 'PPGenericDeriving' to give it a chance to fire before standard 'Pretty'.
instance PPGenericOverride a => GPretty (K1 i a) where
gpretty = ppGenericOverride . unK1
-- | A class to override 'Pretty' when calling 'ppGeneric' without introducing
-- orphans for standard types.
class PPGenericOverride a where
ppGenericOverride :: a -> MetaDoc ann
ppGenericOverrideDoc :: PPGenericOverride a => a -> Doc ann
ppGenericOverrideDoc = mdPayload . ppGenericOverride
newtype PPGenericOverrideToPretty a = PPGenericOverrideToPretty { unPPGenericOverrideToPretty :: a }
instance PPGenericOverride a => Pretty (PPGenericOverrideToPretty a) where
pretty = mdPayload . ppGenericOverride . unPPGenericOverrideToPretty
-- | Fall back to standard 'Pretty' instance when no override is available.
instance Pretty a => PPGenericOverride a where
ppGenericOverride = compositeMetaDoc . pretty
instance {-# OVERLAPS #-} PPGenericOverride Int where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocInt
instance {-# OVERLAPS #-} PPGenericOverride Float where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocFloat
instance {-# OVERLAPS #-} PPGenericOverride Double where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocDouble
instance {-# OVERLAPS #-} PPGenericOverride Integer where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocInteger
instance {-# OVERLAPS #-} PPGenericOverride Natural where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocNatural
instance {-# OVERLAPS #-} PPGenericOverride Word where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocWord
instance {-# OVERLAPS #-} PPGenericOverride Word8 where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocWord8
instance {-# OVERLAPS #-} PPGenericOverride Word16 where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocWord16
instance {-# OVERLAPS #-} PPGenericOverride Word32 where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocWord32
instance {-# OVERLAPS #-} PPGenericOverride Word64 where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocWord64
instance {-# OVERLAPS #-} PPGenericOverride Int8 where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocInt8
instance {-# OVERLAPS #-} PPGenericOverride Int16 where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocInt16
instance {-# OVERLAPS #-} PPGenericOverride Int32 where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocInt32
instance {-# OVERLAPS #-} PPGenericOverride Int64 where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocInt64
instance {-# OVERLAPS #-} PPGenericOverride () where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocUnit
instance {-# OVERLAPS #-} PPGenericOverride Bool where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocBool
instance {-# OVERLAPS #-} PPGenericOverride Char where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = metaDocChar
instance {-# OVERLAPS #-} PPGenericOverride a => PPGenericOverride (Ratio a) where
{-# INLINABLE ppGenericOverride #-}
ppGenericOverride (x :% y) =
ppGenericOverride x <> atomicMetaDoc "/" <> ppGenericOverride y
instance {-# OVERLAPS #-} PPGenericOverride CallStack where
{-# INLINE ppGenericOverride #-}
ppGenericOverride =
compositeMetaDoc . ppCallStack
instance {-# OVERLAPS #-} PPGenericOverride (Doc Void) where
{-# INLINE ppGenericOverride #-}
ppGenericOverride =
compositeMetaDoc . fmap absurd
instance {-# OVERLAPS #-} PPGenericOverride String where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = stringMetaDoc
instance {-# OVERLAPS #-} PPGenericOverride T.Text where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = strictTextMetaDoc
instance {-# OVERLAPS #-} PPGenericOverride TL.Text where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = lazyTextMetaDoc
instance {-# OVERLAPS #-} PPGenericOverride C8.ByteString where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = strictByteStringMetaDoc
instance {-# OVERLAPS #-} PPGenericOverride CL8.ByteString where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = lazyByteStringMetaDoc
instance {-# OVERLAPS #-} PPGenericOverride ShortBS.ShortByteString where
{-# INLINE ppGenericOverride #-}
ppGenericOverride = shortByteStringMetaDoc
instance {-# OVERLAPS #-} PPGenericOverride (ForeignPtr a) where ppGenericOverride = atomicMetaDoc . pretty . show
instance {-# OVERLAPS #-} PPGenericOverride a => PPGenericOverride (TH.TyVarBndr a) where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.OccName where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.NameFlavour where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.PkgName where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.NameSpace where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.ModName where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Name where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.TyLit where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Type where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.SourceUnpackedness where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.SourceStrictness where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Bang where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Con where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Lit where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Bytes where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Stmt where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Guard where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Body where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Match where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Range where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Exp where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Pat where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Clause where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.DerivStrategy where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.DerivClause where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.FunDep where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Overlap where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Callconv where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Safety where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Foreign where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.FixityDirection where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Fixity where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Inline where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.RuleMatch where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Phases where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.RuleBndr where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.AnnTarget where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Pragma where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.TySynEqn where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.FamilyResultSig where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.InjectivityAnn where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.TypeFamilyHead where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Role where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.PatSynArgs where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.PatSynDir where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Dec where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Info where ppGenericOverride = gpretty . from
instance {-# OVERLAPS #-} PPGenericOverride TH.Specificity where ppGenericOverride = gpretty . from
#if MIN_VERSION_template_haskell(2, 21, 0)
instance {-# OVERLAPS #-} PPGenericOverride TH.BndrVis where ppGenericOverride = gpretty . from
#endif
#if MIN_VERSION_template_haskell(2, 22, 0)
instance {-# OVERLAPS #-} PPGenericOverride TH.NamespaceSpecifier where ppGenericOverride = gpretty . from
#endif
instance {-# OVERLAPS #-}
( PPGenericOverride a
, PPGenericOverride b
) => PPGenericOverride (a, b) where
ppGenericOverride (a, b) = atomicMetaDoc $ pretty
( PPGenericOverrideToPretty a
, PPGenericOverrideToPretty b
)
instance {-# OVERLAPS #-}
( PPGenericOverride a
, PPGenericOverride b
, PPGenericOverride c
) => PPGenericOverride (a, b, c) where
ppGenericOverride (a, b, c) = atomicMetaDoc $ pretty
( PPGenericOverrideToPretty a
, PPGenericOverrideToPretty b
, PPGenericOverrideToPretty c
)
instance {-# OVERLAPS #-} PPGenericOverride v => PPGenericOverride (Maybe v) where
ppGenericOverride =
gpretty . from . fmap PPGenericOverrideToPretty
instance {-# OVERLAPS #-} PPGenericOverride v => PPGenericOverride [v] where
ppGenericOverride =
atomicMetaDoc . ppListWith ppGenericOverrideDoc
instance {-# OVERLAPS #-} (PPGenericOverride k, PPGenericOverride v) => PPGenericOverride [(k, v)] where
ppGenericOverride =
atomicMetaDoc . ppAssocListWith ppGenericOverrideDoc ppGenericOverrideDoc
instance {-# OVERLAPS #-} PPGenericOverride k => PPGenericOverride (NonEmpty k) where
ppGenericOverride =
atomicMetaDoc . ppNEWith ppGenericOverrideDoc
instance {-# OVERLAPS #-} PPGenericOverride v => PPGenericOverride (Vector v) where
ppGenericOverride =
atomicMetaDoc . ppVectorWith ppGenericOverrideDoc
instance {-# OVERLAPS #-} (PPGenericOverride k, PPGenericOverride v) => PPGenericOverride (Map k v) where
ppGenericOverride =
atomicMetaDoc . ppMapWith ppGenericOverrideDoc ppGenericOverrideDoc
instance {-# OVERLAPS #-} PPGenericOverride v => PPGenericOverride (Set v) where
ppGenericOverride =
atomicMetaDoc . ppSetWith ppGenericOverrideDoc
instance {-# OVERLAPS #-} (PPGenericOverride k, PPGenericOverride v) => PPGenericOverride (Bimap k v) where
ppGenericOverride =
atomicMetaDoc . ppBimapWith ppGenericOverrideDoc ppGenericOverrideDoc
instance {-# OVERLAPS #-} PPGenericOverride IntSet where
ppGenericOverride =
atomicMetaDoc . ppIntSetWith ppGenericOverrideDoc
instance {-# OVERLAPS #-} PPGenericOverride v => PPGenericOverride (IntMap v) where
ppGenericOverride =
atomicMetaDoc . ppIntMapWith ppGenericOverrideDoc ppGenericOverrideDoc
#ifdef HAVE_ENUMMAPSET
instance {-# OVERLAPS #-} (Enum a, PPGenericOverride a) => PPGenericOverride (EnumSet a) where
ppGenericOverride =
atomicMetaDoc . ppEnumSetWith ppGenericOverrideDoc
instance {-# OVERLAPS #-} (Enum k, PPGenericOverride k, PPGenericOverride v) => PPGenericOverride (EnumMap k v ) where
ppGenericOverride =
atomicMetaDoc . ppEnumMapWith ppGenericOverrideDoc ppGenericOverrideDoc
#endif
instance {-# OVERLAPS #-} PPGenericOverride v => PPGenericOverride (HashSet v) where
ppGenericOverride =
atomicMetaDoc . ppHashSetWith ppGenericOverrideDoc
instance {-# OVERLAPS #-} (PPGenericOverride k, PPGenericOverride v) => PPGenericOverride (HashMap k v) where
ppGenericOverride =
atomicMetaDoc . ppHashMapWith ppGenericOverrideDoc ppGenericOverrideDoc
instance {-# OVERLAPS #-} PPGenericOverride (f (g a)) => PPGenericOverride (Compose f g a) where
ppGenericOverride =
ppGenericOverride . getCompose
instance (GPretty f, GPretty g) => GPretty (f :*: g) where
gpretty (x :*: y) =
compositeMetaDoc $ mdPayload x' <+> mdPayload y'
where
x' = gpretty x
y' = gpretty y
instance GPretty x => GPretty (M1 D ('MetaData a b c d) x) where
gpretty = gpretty . unM1
instance GPretty x => GPretty (M1 S ('MetaSel 'Nothing b c d) x) where
gpretty = gpretty . unM1
instance (KnownSymbol name, GFields x) => GPretty (M1 C ('MetaCons name _fixity 'False) x) where
gpretty (M1 x) =
constructorAppMetaDoc constructor args
where
constructor :: MetaDoc ann
constructor = atomicMetaDoc $ pretty $ symbolVal $ Proxy @name
args :: [MetaDoc ann]
args = toList $ gfields x
class GFields a where
gfields :: a ix -> DList (MetaDoc ann)
instance GFields U1 where
{-# INLINE gfields #-}
gfields = const mempty
instance GPretty x => GFields (M1 S ('MetaSel a b c d) x) where
{-# INLINABLE gfields #-}
gfields = DL.singleton . gpretty . unM1
instance (GFields f, GFields g) => GFields (f :*: g) where
{-# INLINABLE gfields #-}
gfields (f :*: g) = gfields f <> gfields g
instance (KnownSymbol name, GCollectRecord f) => GPretty (M1 C ('MetaCons name _fixity 'True) f) where
gpretty (M1 x) =
compositeMetaDoc $
ppDictHeader
(pretty (symbolVal (Proxy @name)))
(map (fmap mdPayload) (toList (gcollectRecord x)))
class GCollectRecord a where
gcollectRecord :: a ix -> DList (MapEntry Text (MetaDoc ann))
instance (KnownSymbol name, GPretty a) => GCollectRecord (M1 S ('MetaSel ('Just name) su ss ds) a) where
{-# INLINABLE gcollectRecord #-}
gcollectRecord (M1 x) =
DL.singleton (T.pack (symbolVal (Proxy @name)) :-> gpretty x)
instance (GCollectRecord f, GCollectRecord g) => GCollectRecord (f :*: g) where
{-# INLINABLE gcollectRecord #-}
gcollectRecord (f :*: g) = gcollectRecord f <> gcollectRecord g
instance GCollectRecord U1 where
{-# INLINABLE gcollectRecord #-}
gcollectRecord = const mempty