
#7401: Can't derive instance for Eq when datatype has no constructor, while it is trivial do do so. -------------------------------------+------------------------------------- Reporter: jpbernardy | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.6.1 Resolution: | Keywords: deriving, | newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D978 Wiki Page: | -------------------------------------+------------------------------------- Changes (by osa1): * owner: osa1 => @@ -1,10 +1,34 @@ - On a "phantom datatype" D, one gets the message: - {{{ - Can't make a derived instance of `Eq D': - `D' must have at least one data constructor - }}} - However there is a trivial, correct instance of Eq D: - {{{ - instance Eq D where - (==) = undefined - }}} + mpickering reminded me this ticket so before I leave the ownership of this + ticket let me write down the current status: + + Basically there are a couple of things we can do and we just need someone + to + decide which one. + + 1. Implement {{{==}}} as {{{_ == _ = True}}}. Pro: this is consistent with + {{{Void}}}'s {{{Eq}}} instance. Con: I think this lets some bugs to sneak + in. I think it doesn't make sense to compute things based on equality of + empty types, so at this point you've probably made a mistake and it's + better to just bail out. + + 2. Implement {{{==}}} as `x == y = case x of {}`. Pro: it fixes the + problem with (1) and in a good way - you've probably used something like + {{{error "..."}}} for the empty type terms, so you get your error message. + Con: this inconsistent with {{{Void}}}. + + 3. Leave this as is - no {{{deriving (Eq)}}}. This way we make the user + decide which behaviour to have. Pro: You can have whatever you want. Con: + Inconvenient. + + These were also discussed at some point but IIRC most people agree that + these + are bad ideas: + + 4. {{{x == y = error "(==) on empty type"}}}: If it's going to fail it's + better to fail like (2). + + 5. {{{_ == _ = False}}}: Denotationally / type-theoretically bottoms are + equal or something like that? So it's better to implement (1) instead. + + 6. Implement (2), change {{{Void}}}s instance too: Can potentially break + code. New description: mpickering reminded me this ticket so before I leave the ownership of this ticket let me write down the current status: Basically there are a couple of things we can do and we just need someone to decide which one. 1. Implement {{{==}}} as {{{_ == _ = True}}}. Pro: this is consistent with {{{Void}}}'s {{{Eq}}} instance. Con: I think this lets some bugs to sneak in. I think it doesn't make sense to compute things based on equality of empty types, so at this point you've probably made a mistake and it's better to just bail out. 2. Implement {{{==}}} as `x == y = case x of {}`. Pro: it fixes the problem with (1) and in a good way - you've probably used something like {{{error "..."}}} for the empty type terms, so you get your error message. Con: this inconsistent with {{{Void}}}. 3. Leave this as is - no {{{deriving (Eq)}}}. This way we make the user decide which behaviour to have. Pro: You can have whatever you want. Con: Inconvenient. These were also discussed at some point but IIRC most people agree that these are bad ideas: 4. {{{x == y = error "(==) on empty type"}}}: If it's going to fail it's better to fail like (2). 5. {{{_ == _ = False}}}: Denotationally / type-theoretically bottoms are equal or something like that? So it's better to implement (1) instead. 6. Implement (2), change {{{Void}}}s instance too: Can potentially break code. -- Comment: mpickering reminded me this ticket so before I leave the ownership of this ticket let me write down the current status: Basically there are a couple of things we can do and we just need someone to decide which one. 1. Implement {{{==}}} as {{{_ == _ = True}}}. Pro: this is consistent with {{{Void}}}'s {{{Eq}}} instance. Con: I think this lets some bugs to sneak in. I think it doesn't make sense to compute things based on equality of empty types, so at this point you've probably made a mistake and it's better to just bail out. 2. Implement {{{==}}} as {{{x == y = case x of {}}}}. Pro: it fixes the problem with (1) and in a good way - you've probably used something like {{{error "..."}}} for the empty type terms, so you get your error message. Con: this inconsistent with {{{Void}}}. 3. Leave this as is - no {{{deriving (Eq)}}}. This way we make the user decide which behaviour to have. Pro: You can have whatever you want. Con: Inconvenient. These were also discussed at some point but IIRC most people agree that these are bad ideas: 4. {{{x == y = error "(==) on empty type"}}}: If it's going to fail it's better to fail like (2). 5. {{{_ == _ = False}}}: Denotationally / type-theoretically bottoms are equal or something like that? So it's better to implement (1) instead. 6. Implement (2), change {{{Void}}}s instance too: Can potentially break code. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/7401#comment:46 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler