
#8338: Incoherent instances without -XIncoherentInstances -------------------------------------+------------------------------------ Reporter: goldfire | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.6.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by goldfire): It's not clear where the error is among these files. Here are arguments for or against various places: 1. ''The error is the definition of `ShowInstFor`.'' Packaging up an instance may be awkward, but I think it's useful enough not to ban outright. 2. ''The error is the definition of `incoherent`.'' This function has access to multiple instances of the same type, so how is it to choose among them? But, by making this definition an error, we potentially rule out various desirable programs that operate over datatypes that package instances. Because there's no way to pattern-match on a constructor ''without'' making the instance available, these program would become very awkward to write. 3. ''The error is in the type of `fromB`.'' It could be argued that the type of `fromB` should be `Show One => ShowInstFor One`, thus requiring a coherent instance for `Show One` at any use of `fromB`. This seems awkward, and makes the new, constructor-based constraints feel like the old, stupid, datatype-based constraints. 4. ''The error is in the import statements of module `D`.'' We could prohibit importing two modules that export conflicting instances. But, that would cause interoperability problems between different modules/packages that define overlapping instances. And, without a way to control instance import / export, it would be impossible to rectify this problem. 5. ''There is no error here, just a silly programmer.'' I find this dissatisfying, because it is reasonable for a programmer to assume coherence of instances. Yes, this program is silly, indeed, but I feel like dismissing it is somehow weakening Haskell's claim to offer coherence unless the programmer uses "dangerous" extensions, like `OverlappingInstances` or `IncoherentInstances`. 6. ''This is a feature, not a bug.'' We could say that the program above behaves as expected. If this is the case, we need to document the behavior and then maintain it, which I don't think will be particularly easy. So, what to do? I don't honestly know! It may perhaps be best to let sleeping dogs lie (essentially, option 5), but I wanted to document the problem. I should also note that, in GHC 7.8, this becomes much more apparent, because `Coercible` allows you to do this in just one module! To wit: {{{ {-# LANGUAGE GADTs #-} module G where import GHC.Exts data One = One instance Show One where show _ = "datatype One" newtype Two = MkTwo One instance Show Two where show _ = "datatype Two" data ShowInstFor a = Show a => MkSIF showOne :: ShowInstFor One showOne = MkSIF showTwo :: ShowInstFor Two showTwo = coerce showOne incoherent :: ShowInstFor Two -> String incoherent MkSIF = show (MkTwo One) }}} GHCi reports that `incoherent showTwo` is `"datatype One"` and `incoherent MkSIF` is `"datatype Two"`. Yikes! It might also be worth noting that HEAD produces the opposite output on the original program from 7.6.3 -- the `B` and `C` are reversed in the output. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8338#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler