[GHC] #9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas

GHC ghc-devs at haskell.org
Tue Jul 29 08:55:16 UTC 2014


#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
-------------------------------------+-------------------------------------
              Reporter:  simonpj     |            Owner:  diatchki
                  Type:  feature     |           Status:  new
  request                            |        Milestone:
              Priority:  normal      |          Version:  7.8.2
             Component:  Compiler    |         Keywords:
            Resolution:              |     Architecture:  Unknown/Multiple
      Operating System:              |       Difficulty:  Unknown
  Unknown/Multiple                   |       Blocked By:
       Type of failure:              |  Related Tickets:
  None/Unknown                       |
             Test Case:              |
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 Ah yes, thanks.  As you say in comment:16, an instance can have just one
 of these four properties.  But the rules in the user manual then don't
 seem quite right. They currently read thus (in my HEAD, somewhat improved
 from HEAD):
 {{{
 The willingness to be overlapped or incoherent is a property of the
 instance declaration itself, controlled as follows:

  * An instance is overlappable if it has an OVERLAPPABLE or OVERLAPS
    pragama, or if the module in which the instance appears is compiled
    with -XOverlappingInstances.

  * An instance is overlapping if it has an OVERLAPPING or OVERLAPS
    pragama, or if the module in which the instance appears is compiled
    with -XOverlappingInstances.

  * An instance is incoherent if it has an INCOHERENT pragama, or if
    the module in which the instance appears is compiled with
    -XIncoherentInstances.

 Now suppose that, in some client module, we are searching for an instance
 of the target constraint (C ty1 .. tyn). The search works like this.

  * Find all instances I that match the target constraint; that is, the
    target constraint is a substitution instance of I. These instance
    declarations are the candidates.

  * Find all non-candidate instances that unify with the target
    constraint. Such non-candidates instances might match when the
    target constraint is further instantiated. If all of them are
    incoherent, proceed; if not, the search fails.

  * Eliminate any candidate IX for which both of the following hold:
    * There is another candidate IY that is strictly more specific;
      that is, IY is a substitution instance of IX but not vice versa.

    * Either IX is overlappable or IY is overlapping.

  * If only one candidate remains, pick it. Otherwise if all remaining
    candidates are incoherent, pick an arbitrary candidate.
 }}}

 As things stand, and in the implementation, INCOHERENT does not imply
 "overlappable" or "overlapping".  And it probably should.  After all, if
 you have two candidate instances
 {{{
    (incoherent)  C [a]
    (no pragma)   C [Int]
 }}}
 you probably want to pick the latter not the former!  The alternative
 (which I do not advocate) is to treat overlapping and incoherent as
 separate things, so you can say
 {{{
   instance {-# INCOHERENT, OVERLAPPABLE #-} C [a]
 }}}
 So I suggest we change the spec above, and the impl to say
 {{{
  * An instance is overlappable if it has an OVERLAPPABLE or OVERLAPS or
 INCOHERENT
    pragama, or if the module in which the instance appears is compiled
    with -XOverlappingInstances or -XIncoherentInstances.

  ...and similarly "overlapping"
 }}}
 Do you agree?

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9242#comment:20>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list