| 249 | | 1. '''Reject this as a duplicate instance declaration''', which indeed it is. |
| 250 | | 2. '''Allow the explicit to supersede the intrinsic default, but issue a warning''' suggesting to either remove the explicit instance or add an explicit opt-out, or |
| 251 | | 3. '''Allow the explicit to supersede the intrinsic default silently'''. |
| 252 | | |
| 253 | | As it stands, we propose option 1 as somehow the principled thing to |
| 254 | | do. We acknowledge that it creates an issue with legacy code --- that is, it contradicts |
| 255 | | Design Goal 1 --- |
| 256 | | precisely because there are plenty of places where we have written the |
| 257 | | full stack of instances, often just doing the obvious default thing: |
| 258 | | these should be cleaned up, sooner or later. |
| 259 | | |
| 260 | | Option 3 avoids that |
| 261 | | problem but risks perplexity: if I make use of some cool package which |
| 262 | | introduces some {{{Foo :: * -> *}}}, I might notice that {{{Foo}}} is |
| 263 | | a monad and add a {{{Monad Foo}}} instance in my own code, expecting |
| 264 | | the {{{Applicative Foo}}} instance to be generated in concert; to my |
| 265 | | horror, I find my code has subtle bugs because the package introduced |
| 266 | | a different, non-monadic, {{{Applicative Foo}}} instance which I'm |
| 267 | | accidentally using instead. |
| | 249 | 1. '''Reject this as a duplicate instance declaration''', which indeed it is. We acknowledge that it creates an issue with legacy code --- that is, it contradicts Design Goal 1 --- precisely because there are plenty of places where we have written the full stack of instances, often just doing the obvious default thing. |
| | 250 | |
| | 251 | 2. '''Allow the explicit to supersede the intrinsic default, but issue a warning''' suggesting to either remove the explicit instance or add an explicit opt-out. |
| | 252 | |
| | 253 | 3. '''Allow the explicit to supersede the intrinsic default silently'''. This fits with Design Goal 1, but risks perplexity: if I make use of some cool package which introduces some {{{Foo :: * -> *}}}, I might notice that {{{Foo}}} is a monad and add a {{{Monad Foo}}} instance in my own code, expecting the {{{Applicative Foo}}} instance to be generated in concert; to my horror, I find my code has subtle bugs because the package introduced a different, non-monadic, {{{Applicative Foo}}} instance which I'm accidentally using instead. |