Skip to content

SPECIALISE pragmas for derived instances

In package ghc-prim, in GHC.Classes we have

instance (Eq a) => Eq [a] where
    {-# SPECIALISE instance Eq [[Char]] #-}
    {-# SPECIALISE instance Eq [Char] #-}
    {-# SPECIALISE instance Eq [Int] #-}
    []     == []     = True
    (x:xs) == (y:ys) = x == y && xs == ys
    _xs    == _ys    = False

The SPECIALISE instance pragmas instantiate the code for these commonly-used types.

But for tuples we use deriving:

deriving instance (Eq  a, Eq  b) => Eq  (a, b)

and many more similar. There is no way to add a SPECIALISE instance pragma for a derived instance. This is bad, because they are heavily used.

You can see the lossage from messages lie

WARNING: file compiler/specialise/Specialise.lhs, line 673
    specImport discarding:
      GHC.Classes.$w$c== :: forall a b. (Eq a, Eq b) => a -> b -> a -> b -> Bool
        @ Module.Module @ Module.Module Module.$fEqModule Module.$fEqModule

which says that we will end up calling $w$c== for pairs of modules, passing dictionaries to compare the modules for equality. These messages show up when compiling the libraries if you build your stage1 compiler with -DDEBUG.

It should probably be possible to have a top-level

{-# SPECIALISE instance Eq (Int, Bool) #-}

even in another module (as we can now do for functions. To do this right, we'd need to make the code for derived methods INLINEALBE.

Edited by Simon Peyton Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information