eqTypeRep does not inline
GHC never seems to inline eqTypeRep
. That's no good! It produces a Maybe
, which users will almost certainly want to match on immediately.
I really don't understand why it doesn't inline. It's a tiny function, none of the functions it calls are themselves marked INLINE
, and the advantage to inlining seems obvious. Does the unsafeCoerce
get in the way somehow? If so, how can we fix it?
Example:
{-# language GADTs, ScopedTypeVariables, TypeApplications,
AllowAmbiguousTypes #-}
module Foo where
import Type.Reflection
foo :: forall a. Typeable a => Bool
foo = case eqTypeRep (typeRep @a) (typeRep @Int) of
Just _ -> True
Nothing -> False
compiles (with -O2
) to
foo [InlPrag=NOINLINE] :: forall a. Typeable a => Bool
[GblId, Arity=1, Str=<S,1*U>]
foo
= \ (@ a_a5un) ($dTypeable_a5up :: Typeable a_a5un) ->
case eqTypeRep
@ *
@ *
@ a_a5un
@ Int
($dTypeable_a5up
`cast` (base-4.10.1.0:Data.Typeable.Internal.N:Typeable[0] <*>_N <a_a5un>_N
:: (Typeable a_a5un :: Constraint) ~R# (TypeRep a_a5un :: *)))
lvl4_r69g
of {
Nothing -> GHC.Types.False;
Just ds_d5CQ -> GHC.Types.True
}
For reference, eqTypeRep
is defined like this:
eqTypeRep :: forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Maybe (a :~~: b)
eqTypeRep a b
| typeRepFingerprint a == typeRepFingerprint b = Just (unsafeCoerce HRefl)
| otherwise = Nothing