Warn about unwanted instances in a modular way

Henning Thielemann lemming at henning-thielemann.de
Wed Mar 23 13:16:00 UTC 2016


I like to propose the following way to warn about instances that are 
unwanted by some programmers. First step is to mark the instances at their 
definition site like so:

{-# WARN_INSTANCE tuple #-}
instance Foldable ((,) a) where ...

{-# WARN_INSTANCE tuple #-}
instance Functor ((,) a) where ...

{-# WARN_INSTANCE tuple #-}
instance Foldable ((,,) a b) where ...

{-# WARN_INSTANCE tuple #-}
instance Functor ((,,) a b) where ...


This way, all the above instances are collected in an instance group 
labelled 'tuple'. At the use sites we introduce a GHC warning option like 
-fwarn-instance=tuple. This warns about any place where any of the 'tuple' 
instances is used. We can either place

    GHC-Options: -fwarn-instance=tuple

in a Cabal package description in order to issue warnings in a whole 
package or we can put

    {-# OPTIONS_GHC -fwarn-instance=tuple #-}

at the top of a module in order to enable the warning per module.

Another candidate for an instance group might be 'numeric' for numeric 
instances of functions and tuples in the NumInstances package.

What does it mean to use an instance? I would say, if omitting an instance 
X Y would lead to a "missing instance" type error at place Z in a module, 
then instance X Y is used at place Z.

There might be an even more restrictive option like:
    -fforbid-instance=tuple

This would not only warn about an instance usage, but it would cause a 
type error. Essentially it should treat all 'tuple' instances as if they 
were not defined. (Other instances might depend on 'tuple' instances and 
if the 'tuple' instances weren't there the compiler would not even reach 
the current module. I do not know, whether this case needs special 
treatment. We might require that any instance depending on 'tuple' must be 
added to the 'tuple' group as well or it might be added automatically.)
  The advantage of a type error is that we see all problems from 'tuple' 
instances also in the presence of other type errors. Warnings would only 
show up after a module is otherwise type correct.

This solution requires cooperation of the instance implementor. Would that 
work in practice? Otherwise we must think about ways to declare instance 
groups independently from the instance declaration and we get the problem 
of bringing the instance group names into the scope of the importing 
module.

A separate discussion must be held on whether -fwarn-instance=tuple should 
be part of -Wall. I think that people should be warned about 'tuple' 
instances early because they won't expect that there is a trap when using 
'length' and 'maximum' and so on.

One might also think about generalizations, e.g. whether

    {-# WARN_INSTANCE tuple, functor #-}

should be allowed in order to put an instance in several groups or whether 
there should be a way to compose a group from subgroups.

Another topic would be a form of instance group disambiguation. Instance 
groups might be qualified with module or package names. I think package 
names are more appropriate, like so:
    -fwarn-instance=base:tuple


More information about the Glasgow-haskell-users mailing list