Typeclass resolution in Haskell reporting ambiguity even if there is only one instance - haskell

I am experimenting with transitive typeclass instances in Haskell. It is well-known that one cannot declare a transitive instance in the original typeclass (i.e. (C a b, C b c) => C a c). Therefore I tried to define another class representing the transitive closure of the original class instead. Minimal code is as below:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Ambig where
class Coe a b where
from :: a -> b
class CoeTrans a b where
from' :: a -> b
instance CoeTrans a a where
from' = id
instance (Coe a b, CoeTrans b c) => CoeTrans a c where
from' = from' . from #a #b
instance Coe Bool Int where
from False = 0
from True = 1
instance Coe Int Integer where
from x = toInteger x
where CoeTrans is the transitive closure of Coe. When I'm trying to use from' in CoeTrans, however, it always reports ambiguity:
-- >>> from' True :: Integer
-- Ambiguous type variable ‘b0’ arising from a use of ‘from'’
-- prevents the constraint ‘(Coe Bool b0)’ from being solved.
-- Probable fix: use a type annotation to specify what ‘b0’ should be.
-- These potential instance exist:
-- instance Coe Bool Int
-- -- Defined at /Users/t/Desktop/aqn/src/Ambig.hs:21:10
Even if there is virtually only one instance. But according to GHC docs a typeclass resolution will succeed iff there is one applicable instance.
Why would this happen and is there any way to solve the transitive instance problem?

I think you misunderstood the docs a bit. They really say that a typeclass resolution for a given type will succeed iff one instance is present. But in your case, no type is given. b0 is ambiguous.
The compiler needs to know b0 before it can pick an instance of Coe Bool b0, even though there is only one in the current scope. And this is done this way on purpose. And the key words there are "current scope". You see, if the compiler could just pick whatever is available in scope, your program would be vulnerable to subtle changes in scope: you may change your imports, or some of your imported modules may change their internal structure. This may result in different instances appearing or disappearing in your current scope, which may result in different behaviour of your program without any kind of warning.
If you really intend for there to always be at most one unambiguous path between any two types, you can solve it by adding a functional dependency to Coe:
class Coe a b | a -> b where
from :: a -> b
This will have two effects:
The compiler will know that it can always deduce b just by knowing a.
And to facilitate that, the compiler will prohibit multiple instances with same a, but different bs from being defined.
Now the compiler can see that, since the argument of from' is Bool, it must search for an instance of Coe Bool b for some b, and from there it will know for sure what b has to be, and from there it can search for the next instance, and so on.
If, on the other hand, you really intended for there to be multiple possible paths between two given types, and for the compiler to just pick one - you're out of luck. The compiler refuses on principle` to randomly pick one of multiple possibilities - see explanation above.

Related

Ambiguous type variable issue in Haskell

I have read many of the other ambiguous type variable questions on the site but was not able to find a solution to the following issue, although I am new to Haskell so may just not have understood the answers to other questions properly. Simplifying to only include the relevant parts of these definitions, I have a type class
class Dist a where
un :: a
and I have a multiparameter type class
class Dist a => UnBin a b where
opu :: b -> b
opb :: a -> b -> a
where in general a and b are completely unrelated. However, I also have a data type
data LC a b = LC [(a,b)]
and I make it an instance of UnBin using
instance Dist a => UnBin a (LC [(a,b)]) where
opu = ...
opb = ...
where in this particular case, the type LC [(a,b)] already depends on a and I want the two as here to be the same.
What I mean by the two as should be the same is that if I define x = LC [(1 :: Int,'a')]
for example (assuming I have made Int a part of the Dist typeclass already) then I would want to be able to just write opb un x and have Haskell automatically infer that I want un :: Int since a is already determined by the type of x however unless I explicitly use a type signature for un and write opb (un::Int) x I get the error
Ambiguous type variable ‘a0’ arising from a use of ‘un’
prevents the constraint ‘(Dist a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instance exist:
one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
Presumably this means that Haskell is treating the two as in my instance declaration as unrelated when I want them to really be the same. Is there a way to make Haskell automatically able to infer the correct type of un without having to give a type signature every time I want to use un in this way?
Presumably this means that Haskell is treating the two as in my instance declaration as unrelated when I want them to really be the same.
Actually, GHC does know that the two as in the instance you wrote are the same. However, it doesn't know that it should use that instance. The problem is that there could be another instance out there. For instance, for all GHC knows, you've also written the instance:
instance UnBin Char (LC Int b) where
opu = ...
opb = ...
Then, there are two different types that the un in opb un x could be. It really is ambiguous!
But, you might say, I didn't write any other instance. That may be true, but instances are sneaky. If someone imports your code and then creates an orphan instance like the one I wrote above, what should happen? That value opb un x needs to be the same, but with this new instance in scope, it would also need to change. GHC doesn't like this future possibility, so it gives you an error.
You mentioned in your question that "in general a and b are completely unrelated". Hopefully it's the case that a given b implies a given a. If not, or in other words, if you want to be able to write instances like UnBin Char (LC Int b) like I did above, then you're out of luck. You can't have it both ways: you can't have GHC infer the type you want while also keeping the freedom to decide for yourself whatever type you want.
However, if it is true that a and b are related (in that, say, b can imply a), then there are a few ways forward. For instance, as shown by #chi, you can use a type equality in the instance context to trick GHC into matching on the instance you want first and only verifying that the types are the same later. Another option is to use type families or functional dependencies to achieve a similar goal. For instance:
{-# LANGUAGE FunctionalDependencies #-}
class Dist a => UnBin a b | b -> a where
Note that in either case, you're limiting the total number of instances you can write. In the type equality approach, you have generalized your instance head, and with the functional dependency approach, you force b to imply a. Hopefully, that's okay with you.
Fully working example:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE GADTs #-}
class Dist a where
un :: a
instance Dist Int where
un = 42
class Dist a => UnBin a b where
opu :: b -> b
opb :: a -> b -> a
data LC a b = LC [(a,b)]
instance (Dist a, a ~ a') => UnBin a (LC a' b) where
opu = undefined
opb = undefined
x = LC [(1 :: Int,'a')]
test = opb un x -- here GHC infers un::Int as wanted
The main technique is this: instead of writing
instance Dist a => UnBin a (LC a b) where
we write
instance (Dist a, a ~ a') => UnBin a (LC a' b) where
so that the instance head UnBin a (LC a' b) matches even when types a and a' are not the same. Then, we require in the instance context a ~ a' forcing them to be the same.
In this way, the instance is picked during inference at a time where we don't yet know how a and a' are related. After this happens, GHC immediately deduces a~a' and exploits it to infer the type Int for un in test = opb un x.

Overlapping multi-parameter instances and instance specificity

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
module OverlappingSpecificsError where
class EqM a b where
(===) :: a -> b -> Bool
instance {-# OVERLAPPABLE #-} Eq a => EqM a a where
a === b = a == b
instance {-# OVERLAPPABLE #-} EqM a b where
a === b = False
aretheyreallyeq :: (Eq a, Eq b) => Either a b -> Either a b -> Bool
aretheyreallyeq (Left a1) (Right b2) = a1 == b2
aretheyeq :: (Eq a, Eq b) => Either a b -> Either a b -> Bool
aretheyeq (Left a1) (Right b2) = a1 === b2
Neither aretheyreallyeq or aretheyeq compile, but the error for aretheyreallyeq makes sense to me, and also tells me that aretheyeq should not give an error: One of the instances that GHCi suggests are possible for EqM in aretheyeq should be impossible due to the same error on aretheyreallyeq. What's going on?
The point is, GHCi insists that both of the instances of EqM are applicable in aretheyeq. But a1 is of type a and b2 is of type b, so in order for the first instance to be applicable, it would have to have the types a and b unify.
But this should not be possible, since they are declared as type variables at the function signature (that is, using the first EqM instance would give rise to the function being of type Either a a -> Either a a -> Bool, and the error in aretheyreallyeq tells me that GHCi will not allow that (which is what I expected anyway).
Am I missing something, or is this a bug in how overlapping instances with multi-parameter type classes are checked?
I am thinking maybe it has to do with the fact that a and b could be further instantiated later on to the point where they are equal, outside aretheyeq, and then the first instance would be valid? But the same is true for aretheyreallyeq. The only difference is that if they do not ever unify we have an option for aretheyeq, but we do not for aretheyreallyeq. In any case, Haskell does not have dynamic dispatch for plenty of good and obvious reasons, so what is the fear in committing to the instance that will always work regardless of whether later on a and b are unifiable? Maybe there is some way to present this that would make choosing the instance when calling the function possible in some way?
It is worth noting that if I remove the second instance, then the function obviously still does not compile, stating that no instance EqM a b can be found. So if I do not have that instance, then none works, but when that one works, suddenly the other does too and I have an overlap? Smells like bug to me miles away.
Instance matching on generic variables works this way in order to prevent some potentially confusing (and dangerous) scenarios.
If the compiler gave in to your intuition and chose the EqM a b instance when compiling aretheyeq (because a and b do not necessarily unify, as you're saying), then the following call:
x = aretheyeq (Left 'z') (Right 'z')
would return False, contrary to intuition.
Q: wait a second! But in this case, a ~ Char and b ~ Char, and we also have Eq a and Eq b, which means Eq Char, which should make it possible to choose the EqM a a instance, shouldn't it?
Well, yes, I suppose this could be happening in theory, but Haskell just doesn't work this way. Class instances are merely extra parameters passed to functions (as method dictionaries), so in order for there to be an instance, it must either be unambiguously choosable within the function itself, or it must be passed in from the consumer.
The former (unambiguously choosable instance) necessarily requires that there is just one instance. And indeed, if you remove the EqM a a instance, your function compiles and always returns False.
The latter (passing an instance from the consumer) means a constraint on the function, like this:
aretheyeq :: EqM a b => Either a b -> Either a b -> Bool
What you are asking is that Haskell essentially has two different versions of this function: one requiring that a ~ b and picking the EqM a a instance, and the other not requiring that, and picking the EqM a b instance.
And then the compiler would cleverly pick the "right" version. So that if I call aretheyeq (Left 'z') (Right 'z'), the first version gets called, but if I call aretheyeq (Left 'z') (Right 42) - the second.
But now think further: if there are two versions of aretheyeq, and which one to pick depends on whether the types are equal, then consider this:
dummy :: a -> b -> Bool
dummy a b = aretheyeq (Left a) (Right b)
How does dummy know which version of aretheyeq to pick? So now there has to be two versions of dummy as well: one for when a ~ b and another for other cases.
And so on. The ripple effect continues until there are concrete types.
Q: wait a second! Why two versions? Can't there be just one version, which then decides what to do based on what arguments are passed in?
Ah, but it can't! This is because types are erased at compile time. By the time the function starts to run, it's already compiled, and there is no more type information. So everything has to be decided at compile time: which instance to pick, and the ripple effect from it.
It isn't a bug in sense of working exactly as documented. Starting with
Now suppose that, in some client module, we are searching for an instance of the target constraint (C ty1 .. tyn). The search works like this:
The first stage of finding candidate instances works as you expect; EqM a b is the only candidate and so the prime candidate. But the last step is
Now find all instances, or in-scope given constraints, that unify with the target constraint, but do not match it. Such non-candidate instances might match when the target constraint is further instantiated. If all of them are incoherent top-level instances, the search succeeds, returning the prime candidate. Otherwise the search fails.
The EqM a a instance falls into this category, and isn't incoherent, so the search fails. And you can achieve the behavior you want by marking it as {-# INCOHERENT #-} instead of overlappable.
To further complete Alexey's answer, which really gave me the hint at what I should do to achieve the behaviour I wanted, I compiled the following minimum working example of a slightly different situation more alike my real use case (which has to do with ExistentialQuantification):
{-# 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"
If you remove the {-# INCOHERENT #-} annotations, you get exactly the same compile errors as in my original example on both createBar and createBar2, and the point is the same: in createBar it is clear that the only suitable instance is the second one, whereas in createBar2 the only suitable one is the first one, but Haskell refuses to compile because of this apparent confusion it might create when using it, until you annotate them with INCOHERENT.
And then, the code works exactly as you'd expect it to: getA createBar returns Left "abc" whereas getA createBar2 returns Right "defdef", which is exactly the only thing that could happen in a sensible type system.
So, my conclusion is: the INCOHERENT annotation is precisely to allow what I wanted to do since the beginning without Haskell complaining about potentially confusing instances and indeed taking the only one that makes sense. A doubt remains as to whether INCOHERENT may make it so that instances that indeed remain overlapping even after taking into account everything compile, using an arbitrary one (which is obviously bad and dangerous). So, a corollary to my conclusion is: only use INCOHERENT when you absolutely need to and are absolutely convinced that there is indeed only one valid instance.
I still think it is a bit absurd that Haskell has no more natural and safe way to tell the compiler to stop worrying about me being potentially being confused and doing what is obviously the only type checking answer to the problem...
aretheyreallyeq fails because there are two different type variables in scope. In
aretheyreallyeq :: (Eq a, Eq b) => Either a b -> Either a b -> Bool
aretheyreallyeq (Left a1) (Right b2) = a1 == b2
a1 :: a, and b2 :: b, there's no method for comparing values of potentially different types (as this is how they're declared), so this fails. This has nothing to do with any of the enabled extensions or pragmas of course.
aretheyeq fails because there are two instances that could match, not that they definitely do. I'm not sure what version of GHC you're using but here's the exception message I see and it seems to be fairly clear to me:
• Overlapping instances for EqM a b arising from a use of ‘===’
Matching instances:
instance [overlappable] EqM a b -- Defined at /home/tmp.hs:12:31
instance [overlappable] Eq a => EqM a a
-- Defined at /home/tmp.hs:9:31
(The choice depends on the instantiation of ‘a, b’
To pick the first instance above, use IncoherentInstances
when compiling the other instance declarations)
• In the expression: a1 === b2
In an equation for ‘aretheyeq’:
aretheyeq (Left a1) (Right b2) = a1 === b2
In this case, my interpretation is that it's saying that given certain choices for a and b, there are potentially multiple different matching instances.

Trouble with overlapping instances

I'm currently working in a project where I derive some instances for a class. Since the class has only one method with will have the same definition save for a few specific cases, I tried defining an overlappable general instance and then defining the ones I need to be overlapping.
This doesn't work because I get an overlapping instances error. Doing some testing, we came accross this reduced example that's pretty much equivalent to my original problem:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, MultiParamTypeClasses #-}
module Instance where
data Id a = Id a String
data C a = C a
class Bad a b where
bad :: a -> String
instance {-# OVERLAPPABLE #-} Bad a b where
bad = \_ -> "Default case"
instance {-# OVERLAPPING #-} Bad (Id a) (C a) where
bad = \_ -> "Id"
class Good a b where
good :: a -> String
instance {-# OVERLAPPABLE #-} Good a b where
good = \_ -> "Default case"
instance {-# OVERLAPPING #-} Good (Id a) b where
good = \_ -> "Id"
test = let a = Id () "a"
in putStrLn (good a) >> putStrLn (bad a)
(Note that this won't compile unless you comment the second Bad instance.)
Class Good works without any problem (test outputs "Id"). If I don't remove the second instance for Bad, I get:
Overlapping instances for Bad (Id ()) b0
arising from a use of ‘bad’
Matching instances:
instance [overlappable] Bad a b -- Defined at Instance.hs:12:31
instance [overlapping] Bad (Id a) (C a)
-- Defined at Instance.hs:15:30
(The choice depends on the instantiation of ‘b0’
To pick the first instance above, use IncoherentInstances
when compiling the other instance declarations)
In the first argument of ‘putStrLn’, namely ‘(bad a)’
In the second argument of ‘(>>)’, namely ‘putStrLn (bad a)’
In the expression: putStrLn (good a) >> putStrLn (bad a)
What I don't understand is why does this happen, when the only difference between them is an aditional restriction in the second class parameter.
Also, isn't the point of overlappable instances to avoid overlapping errors?
Regards
As per my comment above, I think your pragmas should have AllowAmbiguousTypes instead of UndecidableInstances,
else you get a different error (at least I do on GHC 8.0.1) pertaining to b being ambiguous in the function signature
bad :: Bad a b => a -> String.
AmbiguousTypes allows you to write signatures for functions that will be ambiguous when they are used.
Instead, the ambiguity check is moved to the call-site. This works really well with something like TypeApplications
to specify those ambiguous variables. In this case, bad is always ambiguous, so we need this pragma to move to the
error message at the call-site. Now, I have the same message as you.
The reason that even with OVERLAPPABLE and OVERLAPPING Haskell complains is that depending on how b is instantiated (which hasn't been
specified), it will choose one of the two instances of Bad. In other words, you could want b to unify with C a,
just as well as you could not, so Haskell throws up its hands and says "you haven't told me enough about b for me to be
able to pick a most specific instance of Bad".
On the other hand, even without knowing b, Haskell knows which of the instances Good a b and Good (Id a) b are more
specific - it is always the second one (even without knowing what b is that is the case).
I really recommend you read the documentation about overlapping instances
as it explains the whole algorithm.
You can usually get around these problems using things like TypeApplications (to specify b), or translating your type class to a type family.

Resolving type ambiguities using available class instances

Given the following code:
import Data.Word
data T = T deriving (Eq, Show)
class C a where f :: a -> ()
instance C T where f _ = ()
instance C Word16 where f _ = ()
main = return $ f 0x16
GHC complains that it can't infer what the type for the literal 0x16 should be with the error:
No instance for (Num a0) arising from the literal ‘22’
The type variable ‘a0’ is ambiguous
It is easy to see why this would be -- Haskell allows numeric literals to be of any type which has an instance of Num, and here we can't disambiguate what the type for the literal 0x16 (or 22) should be.
It's also clear as a human reading this what I intended to do -- there is only one available instance of the class C which satisfies the Num constraint, so obviously I intended to use that one so 0x16 should be treated as a Word16.
There are two ways that I know to fix it: Either annotate the literal with its type:
main = return $ f (0x16 :: Word16)
or define a function which essentially does that annotation for you:
w16 x = x :: Word16
main = return $ f (w16 0x16)
I have tried a third way, sticking default (Word16) at the top of the file in the hope that Haskell would pick that as the default type for numeric literals, but I guess I'm misunderstanding what the default keyword is supposed to do because that didn't work.
I understand that typeclasses are open, so just because you can make the assumption in the context quoted above that Word16 is the only numeric instance of C that may not hold in some other module. But my question is: is there some mechanism by which I can assume/enforce that property, so that it is possible to use f and have Haskell resolve the type of its numeric argument to Word16 without explicit annotations at the call site?
The context is that I am implementing an EDSL, and I would rather not have to include manual type hints when I know that my parameters will either be Word16 or some other non-numeric type. I am open to a bit of dirty types/extensions abuse if it makes the EDSL feel more natural! Although if solutions do involve the naughty pragmas I'd definitely appreciate hints on what I should be wary about when using them.
Quick solution with "naughty pragmas" with GHC 7.10:
{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
class C a where f :: a -> ()
instance C T where f _ = ()
instance {-# INCOHERENT #-} (w ~ Word16) => C w where f _ = ()
And with GHC 7.8:
{-# LANGUAGE TypeFamilies, FlexibleInstances, IncoherentInstances #-}
class C a where f :: a -> ()
instance C T where f _ = ()
instance (w ~ Word16) => C w where f _ = ()
Here, GHC essentially picks an arbitrary most specific instance that remains after trying to unify the instances heads and constraints.
You should only use this if
You have a fixed set of instances and don't export the class.
For all use cases of the class method, there is a single possible most specific instance (given the constraints).
Many people advise against ever using IncoherentInstances, but I think it can be quite fun for DSL-s, if we observe the above considerations.
For anybody else wondering about default (I know I was!)
https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3
Quoting section 4.3.4:
In situations where an ambiguous type is discovered, an ambiguous type variable, v, is defaultable if:
v appears only in constraints of the form C v, where C is a class, and
at least one of these classes is a numeric class, (that is, Num or a subclass of Num), and
all of these classes are defined in the Prelude or a standard library.
So that explains why your default clause is being completely ignored; C is not a standard library type-class.
(As to why this is the rule… can't help you there. Presumably to avoid breaking arbitrary user-defined code.)

Why does this instance fail the coverage condition?

Why does the following instance declaration fail the coverage condition in the absence of UndecidableInstances? It seems that if the functional dependency is satisfied in the context then it is satisfied in the new instance.
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
class Foo a b | a -> b where
instance (Foo a b, Foo a' b') => Foo (a, a') (b, b') where
If I try to replicate the same thing with a type family there is no problem.
{-# LANGUAGE TypeFamilies #-}
type family Bar a
type instance Bar (a, b) = (Bar a, Bar b)
I believe it's that constraints on instances aren't actually taken into account when selecting an instance. They become additional constraints to be proved at each use site, rather than limiting the applicability of the instance.
So your instance declaration is kind of equivalent to instance Foo (a, b) (c, d), which rather obviously fails the coverage condition.
Adding the (Foo a b, Foo a' b') only makes it so that some of the uses of the instance would result in "no such instance" errors, it doesn't actually change the types for which your instance will be selected.
From the GHC docs:
The Coverage Condition. For each functional dependency, tvsleft ->
tvsright, of the class, every type variable in S(tvsright) must appear
in S(tvsleft), where S is the substitution mapping each type variable
in the class declaration to the corresponding type in the instance
declaration.
In your class you have a -> b, so tvsleft = a and tvsright = b.
The substitution S maps a into S(a)=(a,a') and b into S(b)=(b,b').
So, we find type variables in S(tvsright)=S(b)=(b,b') (both b and b') which do not
appear in S(tvsleft)=S(a)=(a,a'). Hence the coverage condition fails.
As #Ben said, the coverage condition does not take the context into account:
only the instance head matters.

Resources