Type.Reflection code takes long to compile (48s on 8.10, 12s on 9.3)
This code takes around 48s to compile on ghc 8.10 and around 12s to compile on ghc 9.3.20210709. Maybe this is something you are interested in taking a closer look at. The example relies heavily on Type.Reflection
, I have not minimized it but I am attempting to define generic implementations without using an adhoc typeclass definition.
{-# Language FlexibleContexts #-}
{-# Language GADTs #-}
{-# Language PatternSynonyms #-}
{-# Language PolyKinds #-}
{-# Language ScopedTypeVariables #-}
{-# Language StandaloneKindSignatures #-}
{-# Language TypeApplications #-}
{-# Language TypeOperators #-}
{-# Language ViewPatterns #-}
import qualified GHC.Generics as GHC
import GHC.Generics hiding (Constructor, S)
import Type.Reflection
import Data.Kind
is :: forall a b. Typeable a => TypeRep b -> Maybe (a :~~: b)
is = eqTypeRep (typeRep @a)
gcountFields :: forall f a. Typeable @(Type -> Type) f => f a -> Int
gcountFields as
| (is @(V1 @Type) -> Just HRefl) <- typeRep @f
= 0
| (is @(U1 @Type) -> Just HRefl) <- typeRep @f
= 1
| k1 `App` TypeRep `App` TypeRep <- typeRep @f
, (is @(K1 @Type) -> Just HRefl) <- k1
= 1
| m1 `App` i `App` c `App` TypeRep <- typeRep @f
, (is @(M1 @Type) -> Just HRefl) <- m1
, M1 a <- as
= gcountFields a
| or `App` TypeRep `App` TypeRep <- typeRep @f
, (is @((:+:) @Type) -> Just HRefl) <- or
= case as of
L1 a -> gcountFields a
R1 a -> gcountFields a
| and `App` TypeRep `App` TypeRep <- typeRep @f
, (is @((:*:) @Type) -> Just HRefl) <- and
, a :*: b <- as
= gcountFields a + gcountFields b
countFields :: Generic a => Typeable (Rep a) => a -> Int
countFields = gcountFields . from
{-
-- Uncomment for versions before TypeRep was added to base
type TypeableInstance :: forall k. k -> Type
data TypeableInstance :: forall k. k -> Type where
TypeableInstance :: Typeable a => TypeableInstance a
typeableInstance :: forall (k :: Type) (a :: k). TypeRep a -> TypeableInstance a
typeableInstance rep = withTypeable rep TypeableInstance
pattern TypeRep :: forall (k :: Type) (a :: k). () => Typeable a => TypeRep a
pattern TypeRep <- (typeableInstance -> TypeableInstance)
where TypeRep = typeRep
-}