[GHC] #7401: Can't derive instance for Eq when datatype has no constructor, while it is trivial do do so.
GHC
ghc-devs at haskell.org
Tue May 10 20:26:32 UTC 2016
#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
More information about the ghc-tickets
mailing list