Draft: Remove cycle between GHC.Base and Data.Semigroup.Internal
Semigroup
is defined in GHC.Base
, because it is a superclass of
Monoid
, which is a constraint on tuple instances of Applicative
and
Monad
. This introduces a complication. The stimes
method of
Semigroup
has an Integral
constraint, and Integral
is defined in
GHC.Real
, which imports GHC.Base
. Fun times. Previously, this was
addressed by having an hs-boot
file for GHC.Real
exposing the
existence of Integral
, and defining the actual stimes
implementations in Data.Semigroup.Internal
, which had an hs-boot
file so GHC.Base
could see them.
All good? Not really. This arrangement meant that none of the stimes
implementations in Data.Semigroup.Internal
, including even the
default implementation of stimes
, could be inlined or specialized
anywhere. They were totally opaque.
New plan: Get rid of the hs-boot
files for Data.Semigroup.Internal
and GHC.Base
. In their place, add ones for GHC.Enum
and GHC.Num
and expand the one for GHC.Real
. Why are these better than the one for
Data.Semigroup.Internal
? They export only classes and types, not
bindings (or instances). So the inlining barrier is removed and no new
one is introduced.
What's the deal with the (quite substantial) compile-time metric
increases on some tests? Each of those tests defines at least one
Semigroup
instance that does not define stimes
explicitly. So the
default implementation, which is now subject to specialization, is used.
I can't guess why the metric increases are so large, though; there are
no new {-# INLINE #-}
pragmas or anything otherwise suspicious.
Test changes