Skip to content

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
-}
Edited by Icelandjack
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information