[GHC] #10577: Use empty cases where appropriate when deriving instances for empty types

GHC ghc-devs at haskell.org
Fri Jun 26 16:23:10 UTC 2015


#10577: Use empty cases where appropriate when deriving instances for empty types
-------------------------------------+-------------------------------------
              Reporter:  rwbarton    |             Owner:
                  Type:  bug         |            Status:  new
              Priority:  normal      |         Milestone:
             Component:  Compiler    |           Version:  7.11
              Keywords:              |  Operating System:  Unknown/Multiple
          Architecture:              |   Type of failure:  None/Unknown
  Unknown/Multiple                   |        Blocked By:
             Test Case:              |   Related Tickets:
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------
 In some sense the correct instance for
 {{{
 data X
 deriving instance Eq X
 }}}
 is not (what GHC currently produces)
 {{{
 instance Eq X where
   (==) = error "Void =="
 }}}
 but rather
 {{{
 instance Eq X where
   a == b = case a of {}     -- using the EmptyCase extension
 }}}
 See comments starting at ticket:7401#comment:28 for justification.

 The list of classes that GHC can currently derive is

 * Eq, Ord, Enum, Bounded, Show, Read (Haskell 2010 Report)
 * Functor, Foldable, Traversable, Typeable, Generic, Data, "any class"
 (`-XDerive*`)

 Deriving Enum and Bounded is not currently allowed for empty data types.
 The `showList` method of Show and the whole Read instance are easy and
 already implemented correctly. All the remaining methods of Haskell 2010
 derivable type classes take at least one argument of the instance head
 type `a`. I propose that all these methods be defined as an empty case on
 the first such argument.

 Similarly in Functor, Foldable and Traversable, each method has a single
 argument of the form `t _` where `t :: * -> *` is the instance head type,
 and the method should be defined as an empty case on that argument.

 In all these cases so far, the derived methods for a non-empty type would,
 at the outermost level, be a (non-empty) case on that first argument, or
 the equivalent (series of pattern matches, one for each constructor), so
 the use of an empty case is justified for an empty type.

 Typeable does not care about the values or even the kind of the type at
 all, so it's not relevant here.

 Generic and especially Data are above my pay grade, but generally I expect
 that methods which are normally defined by case analysis on an argument of
 the instance head type should be defined by an empty case, and methods
 that (sometimes) produce a value of the instance head type should do
 whatever they normally do when unable to produce such a value (like
 `readsPrec` returning an empty list, or `read` calling `error` (if `read`
 were actually a method of `Read`)).

 `DeriveAnyClass` doesn't generate any new code, so like Typeable it's not
 relevant.

 None of this behavior is specified by the Haskell 2010 Report, which
 disallows deriving any class for a type with no constructors; but see
 #7401. So, we are entitled to do what we think is best here.

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


More information about the ghc-tickets mailing list