Skip to content

Unused instances retained

Since instances are global, GHC always exports them. Normally, this is fine. With Typeable, it often leads to unnecessary junk in object files, interface files, and dumps. For example, consider this (complete) module

module Foo (sauce)

data Res = Goodness | Gracious
  deriving Enum
stir :: Int -> Res
sauce :: Int -> Bool
sauce = toEnum . fromEnum . stir

GHC will produce all the bindings for Typeable Res, Typeable 'Goodness and Typeable 'Gracious, none of which can ever be used. It also exports an Enum instance for Res which is unusable outside the module (and which will be optimized out of existence inside it). It would be really nice to find a way to clean up at least the totally unused/unusable bindings.

I think the key idea is to come up with (a conservative approximation of?) when a type is "exported". Only instances of exported types should be considered "GC roots" for cleanup. Any type listed in an export list is immediately considered exported. Similarly, any type that appears in the type signature of an exported binding or data constructor is immediately considered exported. I imagine the tricky bits will be in type/data families and maybe functional dependencies. But even the most conservative approximations will probably clean up the vast majority of the crud.

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