Why does this instance fail the coverage condition? - haskell

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.

Related

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

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.

Apply constraint within constraint in Haskell

Is there anyway to apply a constraint within another constraint such that this
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE KindSignatures #-}
module Test where
type Con a = (Num a, Show a)
type App c a b = (c a, c b)
program :: App Con a b => a -> b -> String
program a b = show a ++ " " ++ show (b+1)
will work?
Currently GHC is giving me the following errors:
[1 of 1] Compiling Test ( Test.hs, interpreted )
Test.hs:9:12: error:
• Expected a constraint, but ‘App Con a b’ has kind ‘*’
• In the type signature: program :: App Con a b => a -> b -> String
|
9 | program :: App Con a b => a -> b -> String
| ^^^^^^^^^^^
Test.hs:9:16: error:
• Expected kind ‘* -> *’, but ‘Con’ has kind ‘* -> Constraint’
• In the first argument of ‘App’, namely ‘Con’
In the type signature: program :: App Con a b => a -> b -> String
|
9 | program :: App Con a b => a -> b -> String
| ^^^
Failed, no modules loaded.
Thanks!
An easy way to fix this is to use the LiberalTypeSynonyms extension. This extension allows GHC to first treat the type synonyms as substitutions and only afterwards check that the synonyms are fully applied. Note that GHC can be a little silly at kind inference, so you'll need to be very clear with it (i.e., an explicit signature). Try this:
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LiberalTypeSynonyms #-}
module Test where
import Data.Kind (Constraint)
type Con a = (Num a, Show a)
type App c a b = (c a, c b) :: Constraint
program :: App Con a b => a -> b -> String
program a b = show a ++ " " ++ show (b+1)
Before I understood that this could be solved with LiberalTypeSynonyms, I had a different solution, which I'll keep here in case anyone's interested.
Although the error message you're getting is a bit misleading, the fundamental problem with your code comes down to the fact that GHC does not support partial application of type synonyms, which you have in App Con a b. There are a few ways to fix this, but I find the simplest is to convert the type synonym constraint into a class constraint following this pattern:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
type Con' a = (Num a, Show a)
class Con' a => Con a
instance Con' a => Con a
You can use this definition of Con anywhere you were intending to use your old one.
If you're interested in how/why this works, it's basically a trick to get around GHC's lack of support for partial type synonym/family application for the particular cases where those type synonyms/families define simple constraints.
What we're doing is defining a class, and every class comes with a constraint of the same name. Now, notice that the class has no body, but critically, the class itself has a constraint (in the above case Con' a), which means that every instance of the class must have that same constraint.
Next, we make an incredibly generic instance of Con, one that covers any type so long as the constraint Con' holds on that type. In essence, this assures that any type that is an instance of Con' is also an instance of Con, and the Con' constraint on the Con class instance assures that GHC knows that anything that's an instance of Con also satisfies Con'. In total, the Con constraint is functionally equivalent to Con', but it can be partially applied. Success!
As another side note, the GHC proposal for unsaturated type families was recently accepted, so there may be a not-too-far-off future where these tricks are unnecessary because partial application of type families becomes allowed.
Haskell does not support type-level lambdas, nor partial application of type families / type synonyms. Your Con must always be fully applied, it can not passed unapplied to another type synonym.
At best, we can try to use "defunctionalization" as follows, effectively giving names to the type-level lambdas we need.
{-# LANGUAGE ConstraintKinds, KindSignatures, TypeFamilies #-}
import Data.Kind
-- Generic application operator
type family Apply f x :: Constraint
-- A name for the type-level lambda we need
data Con
-- How it can be applied
type instance Apply Con x = (Show x, Num x)
-- The wanted type-level function
type App c a b = (Apply c a, Apply c b)
-- Con can now be passed since it's a name, not a function
program :: App Con a b => a -> b -> String
program a b = show a ++ " " ++ show (b+1)
To call App with a different first argument, one would need to repeat this technique: define a custom dummy type name (like Con) and describe how to apply it (using type instance Apply ... = ...).

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.

Constraint Inference from Instances

Consider the following:
{-# LANGUAGE FlexibleContexts #-}
module Foo where
data D a = D a
class Foo b
instance (Num a) => Foo (D a)
f :: (Foo (D a)) => a -> a
f x = x+1
GHC complains that it cannot deduce Num a in f. I would like this constraint to be inferred from the (non-overlapping) instance of Foo for D a.
I know I could use a GADT for D and add the constraint Num a there, but I'm hoping to not have to pollute the constructor for D with lots of unnecessary constraints. Is there any hope of this ever happening, and is it possible now?
I am guessing this would break for overlapping instances, and therefore is not inferred in general. That is, you could have
{-# LANGUAGE OverlappingInstances #-}
...
instance (Num a) => Foo (D a)
instance Foo (D Bool)
and then your desired inference would certainly not be sound.
EDIT: Looking more closely at the documentation, it is possible to have
{-# LANGUAGE FlexibleContexts #-}
module Foo where
data D a = D a
class Foo b
instance (Num a) => Foo (D a)
f :: (Foo (D a)) => a -> a
f x = x+1
and then in a separate file:
{-# LANGUAGE OverlappingInstances #-}
module Bar where
import Foo
instance Foo Bool
test = f True
That is, the documentation implies only one of the modules defining the two instances needs to have the OverlappingInstances flag, so if Foo.f were definable as this, you could make another module Bar break type safety completely. Note that with GHC's separate compilation, f would be compiled completely without knowledge of the module Bar.
The arrow => is directional. It means that if Num a holds then Foo (D a). It does not mean that if Foo (D a) holds then Num a holds.
The knowledge that there are (and will never be) any overlapping instances for Foo (D a) should imply that the reverse implication is also true, but (a) GHC doesn't know this and (b) GHC's instance machinery is not set up to use this knowledge.
To actually compile functions that use type classes, it's not enough for GHC to merely prove that a type must be an instance of a class. It has to actually come up with a specific instance declaration that provides definitions of the member functions. We need a constructive proof, not just an existence proof.
To identify an instance of class C, it can either reuse one that will be chosen by the caller of the function being compiled, or it must know the types involved concretely enough to select a single instance from those available. The function being compiled will only be passed an instance for C if it has a constraint for C; otherwise the function must be sufficiently monomorphic that it can only use a single instance.
Considering your example specifically, we can see that f has a constraint for Foo (D a), so we can rely on the caller providing that for us. But the caller isn't going to give us an instance for Num a. Even if you presume that we know from the Num a constraint on Foo (D a) that there must be such an instance out there somewhere, we have no idea what a is, so which definition of + should we invoke? We can't even call another function that works for any Num a but is defined outside the class, because they will all have the Num a constraint and thus expect us to identify an instance for them. Knowing that there is an instance without having having the instance is just not useful.
It isn't at all obvious, but what you're actually asking GHC to do is to do a runtime switch on the type a that arrives at runtime. This is impossible, because we're supposed to be emitting code that works for any type in Num, even types that don't exist yet, or whose instances don't exist yet.
A similar idea that does work is when you have a constraint on the class rather than on the instance. For example:
class Num a => Foo a
f :: Foo a => a -> a
f x = x + 1
But this only works because we know that all Foo instances must have a corresponding Num instance, and thus all callers of a function polymorphic in Foo a know to also select a Num instance. So even without knowing the particular a in order to select a Num instance, f knows that its caller will also provide a Num instance along with the Foo instance.
In your case, the class Foo knows nothing about Num. In other examples Num might not even be defined in code accessible to the module where the class Foo is defined. It's the class that sets the required information that has to be provided to call a function that is polymorphic in the type class, and those polymorphic functions have to be able to work without any knowledge specific to a certain instance.
So the Num a => Foo (D a) instance can't store the Num instance - indeed, the instance definition is also polymorphic in a, so it's not able to select a particular instance to store even if there was space! So even though f might be able to know that there is a Num a instance from Foo (D a) (if we presume certain knowledge that no overlapping could ever be involved), it still needs a Num a constraint in order to require its callers to select a Num instance for it to use.

Resources