
Hello all, This stems from a Stack Overflow question that I posted a few days ago: https://stackoverflow.com/questions/60199424/overlapping-multi-parameter-ins... I'd like to hear either agreement or a more convincing argument as to why GHCi behaves the way it does in this case, since the ones at Stack Overflow basically told me that it does to "protect me from being too dumb and not understanding my own code", the way I interpret it. I felt that was totally against the principles of Haskell, so I thought there must be more. I'm going to focus on my second example (on my own answer to the question) for the sake of clarity here. Consider the following code: {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ExistentialQuantification #-} module ExistentialTest where class Class1 a b where foo :: a -> b instance {-# INCOHERENT #-} Monoid a => Class1 a (Either b a) where foo x = Right (x <> x) instance {-# INCOHERENT #-} Monoid a => Class1 a (Either a b) where foo x = Left x data Bar a = Dir a | forall b. Class1 b a => FromB b getA :: Bar a -> a getA (Dir a) = a getA (FromB b) = foo b createBar :: Bar (Either String t) createBar = FromB "abc" createBar2 :: Bar (Either t String) createBar2 = FromB "def" This code compiles, but only because of the INCOHERENT annotations. If you remove those, it will give overlapping instances errors on both createBar and createBar2. I argue that those errors are senseless, because, while if t were instantiated to String then those instances would be valid, the functions createBar and createBar2 are by definition polymorphic, and the only way to make those functions work for every t is to use specifically one of the instances on each case. Therefore, the compiler should realize this, use that instance, and not complain about it. When using the INCOHERENT annotations it works, and uses the right instance on each case (because of course it would, the other instance is absolutely unusable in each of the cases). The best argument that I was given on stack overflow is that allowing that would make it confusing because people might use those polymorphic functions with the specific t ~ String instantiation of the types and expect the behaviour to use the instance that is not usable in general. I find that a really poor argument. A user of the function need not know in general how a function internally works (that it uses the Class1 instance, which is not a constraint on the function signature), and it would be way too much for a user of the function to look at that code (that they should not need to look at), and then guess which instance it might be using, and guess wrong. Having GHCi protect me from that highly hypothetical situation while preventing me from compiling theoretically correct programs seems strange at best. I have tried to think of potential situations where a similar kind of ambiguity might affect the actual type checking and not just what the user might (wrongly) think of it, but I haven't found any. From what I understand, though, the INCOHERENT annotation is dangerous in that if there were other instances which in fact did match in general, then GHCi would choose an arbitrary one. Therefore, I'd like them out of my code. Are there any comments on this that give me a more theoretical reason as to why Haskell disallows this without the INCOHERENT annotations? Is it worth proposing a change to the compiler to allow this? It basically seems that the compiler is checking the overlapping instances "too soon" before realizing that t cannot be unified with String within createBar, because it is a forall quantified polymorphic function. A way to see this is to precisely comment one of the instances and realize that you still get one error on each function, and on the one you removed the right instance for, it will actually say that there is no instance at all. It feels wrong that Haskell can tell you there are two instances that would match, and when you remove one of them, it tells you that there are no instances that match. That in of itself screams bug to me until someone gives me a really convincing explanation of why that is okay. Thanks once again for any time you spent on this, haskell-cafe. Juan Casanova. -- The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336.