Haskell/GHC: overlapping instances reported while context only allows a single one - haskell

Dear Haskell/GHC experts,
I don't really understand why GHC reports overlapping instances while only one is actually valid according the provided contexts. For instance, let's consider the following piece of code:
{-# LANGUAGE FlexibleInstances #-}
class C a where
foo :: a -> String
foo x = "OK"
instance C Bool
instance (C a) => C [a]
instance (C a) => C [(Char, a)]
main = print $ foo [('a', True)]
Compiling it gives:
Test.hs:13:16: error:
* Overlapping instances for C [(Char, Bool)]
arising from a use of `foo'
Matching instances:
instance C a => C [a] -- Defined at Test.hs:9:10
instance C a => C [(Char, a)] -- Defined at Test.hs:11:10
* In the second argument of `($)', namely `foo [('a', True)]'
In the expression: print $ foo [('a', True)]
In an equation for `main': main = print $ foo [('a', True)]
The point is that ('a', True) has type (Char, Bool) which is not an instance of C. Therefore, instance C a => C [a] is not applicable to the value [('a', True)].
Therefore, why does GHC consider it?
The question is really about understanding the behaviour of GHC, not about how to avoid the issue (e.g. using OverlappingInstances). Is it because contexts are not used when "resolving" a function call? And if so, why?
Thanks in advance!

My understanding (could be very wrong):
First, from the documentation:
When matching, GHC takes no account of the context of the instance
declaration (context1 etc). GHC's default behaviour is that exactly
one instance must match the constraint it is trying to resolve. It is fine for there to be a potential of overlap (by including both declarations (A) and (B), say); an error is only reported if a particular constraint matches more than one.
The -XOverlappingInstances flag instructs GHC to allow more than one
instance to match, provided there is a most specific one.
In your case, the type passed to foo is [(Char,Bool)]. This satisfies the generic [a] and the more specialised [(Char,a)]. In the absence of OverlappingInstances flag, the most specific match scenario does not apply, and an error is reported.
Now if you were to tweak your code slightly like so:
instance C Bool
instance (C a) => C [a]
instance (C a) => C (Char, a)
Then there would be no overlap, because a tuple is not a list.

Related

Why is `succ i` valid where `i :: Num a => a` (and not an `Enum a`)?

This seems to apply to both GHCi and GHC. I'll show an example with GHCi first.
Given i type has been inferred as follows:
Prelude> i = 1
Prelude> :t i
i :: Num p => p
Given that succ is a function defined on Enum:
Prelude> :i Enum
class Enum a where
succ :: a -> a
pred :: a -> a
-- …OMITTED…
and that Num is not a 'subclass' (if I can use that term) of Enum:
class Num a where
(+) :: a -> a -> a
(-) :: a -> a -> a
-- …OMITTED…
why succ i does not return an error?
Prelude> succ i
2 -- works, no error
I would expect :type i to be inferred to something like:
Prelude> i = 1
Prelude> :type i
i :: (Enum p, Num p) => p
(I'm using 'GHC v. 8.6.3')
ADDITION:
After reading #RobinZigmond comment and #AlexeyRomanov answer I have noticed that 1 could be interpreted as one of many types and one of many classes.
Thanks to #AlexeyRomanov answer I understand much more about the defaulting-rules used to decide what type to use for ambiguous expressions.
However I don't feel that Alexey answer addresses exactly my question. My question is about the type of i. It's not about the type of succ i.
It's about the mismatch between succ argument type (an Enum a) and the apparent type of i (a Num a).
I'm now starting to realise that my question must stem from a wrong assumption: 'that once i is inferred to be i :: Num a => a, then i can be nothing else'. Hence I was puzzled to see succ i was evaluated without errors.
GHC also seems to be inferring Enum a in addition to what was explicitly declared.
x :: Num a => a
x = 1
y = succ x -- works
However it is not adding Enum a when the type variable appears as a function:
my_succ :: Num a => a -> a
my_succ z = succ z -- fails compilation
To me it seems that the type constraints attached to a function are stricter to the ones applied to a variable.
GHC is saying my_succ :: forall a. Num a => a -> a and given
forall a doesn't appear in the type-signature of neither i nor x I thought that meant GHC is not going to infer any more classes for my_succ types.
But this seems again wrong: I've checked this idea with the following (first time I type RankNTypes) and apparently GHC still infers Enum a:
{-# LANGUAGE RankNTypes #-}
x :: forall a. Num a => a
x = 1
y = succ x
So it seems that inference rules for functions are stricter than the ones for variables?
Yes, succ i's type is inferred as you expect:
Prelude> :t succ i
succ i :: (Enum a, Num a) => a
This type is ambiguous, but it satisfies the conditions in the defaulting rules for GHCi:
Find all the unsolved constraints. Then:
Find those that are of form (C a) where a is a type variable, and partition those constraints into groups that share a common type variable a.
In this case, there's only one group: (Enum a, Num a).
Keep only the groups in which at least one of the classes is an interactive class (defined below).
This group is kept, because Num is an interactive class.
Now, for each remaining group G, try each type ty from the default-type list in turn; if setting a = ty would allow the constraints in G to be completely solved. If so, default a to ty.
The unit type () and the list type [] are added to the start of the standard list of types which are tried when doing type defaulting.
The default default-type list (sic) is (with the additions from the last clause) default ((), [], Integer, Double).
So when you do Prelude> succ i to actually evaluate this expression (note :t doesn't evaluate the expression it gets), a is set to Integer (first of this list satisfying the constraints), and the result is printed as 2.
You can see it's the reason by changing the default:
Prelude> default (Double)
Prelude> succ 1
2.0
For the updated question:
I'm now starting to realise that my question must stem from a wrong assumption: 'that once i is inferred to be i :: Num a => a, then i can be nothing else'. Hence I was puzzled to see succ i was evaluated without errors.
i can be nothing else (i.e. nothing that doesn't fit this type), but it can be used with less general (more specific) types: Integer, Int. Even with many of them in an expression at once:
Prelude> (i :: Double) ^ (i :: Integer)
1.0
And these uses don't affect the type of i itself: it's already defined and its type fixed. OK so far?
Well, adding constraints also makes the type more specific, so (Num a, Enum a) => a is more specific than (Num a) => a:
Prelude> i :: (Num a, Enum a) => a
1
Because of course any type a that satisfies both constraints in (Num a, Enum a) satisfies just Num a.
However it is not adding Enum a when the type variable appears as a function:
That's because you specified a signature which doesn't allow it to. If you don't give a signature, there's no reason to infer Num constraint. But e.g.
Prelude> f x = succ x + 1
will infer the type with both constraints:
Prelude> :t f
f :: (Num a, Enum a) => a -> a
So it seems that inference rules for functions are stricter than the ones for variables?
It's actually the other way around due to the monomorphism restriction (not in GHCi, by default). You've actually been a bit lucky not to run into it here, but the answer is already long enough. Searching for the term should give you explanations.
GHC is saying my_succ :: forall a. Num a => a -> a and given forall a doesn't appear in the type-signature of neither i nor x.
That's a red herring. I am not sure why it's shown in one case and not the other, but all of them have that forall a behind the scenes:
Haskell type signatures are implicitly quantified. When the language option ExplicitForAll is used, the keyword forall allows us to say exactly what this means. For example:
g :: b -> b
means this:
g :: forall b. (b -> b)
(Also, you just need ExplicitForAll and not RankNTypes to write down forall a. Num a => a.)

Ambiguous type variable in a test for empty list

Consider the following snippet which defines a function foo which takes in a list and performs some operation on the list (like sorting).
I tried to load the snippet in ghci:
-- a function which consumes lists and produces lists
foo :: Ord a => [a] -> [a]
foo [] = []
foo (x:xs) = xs
test1 = foo [1, 2, 3] == [2, 3]
test2 = null $ foo []
yet the following error occurs:
No instance for (Ord a0) arising from a use of ‘foo’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance (Ord a, Ord b) => Ord (Either a b)
-- Defined in ‘Data.Either’
instance forall (k :: BOX) (s :: k). Ord (Data.Proxy.Proxy s)
-- Defined in ‘Data.Proxy’
instance (GHC.Arr.Ix i, Ord e) => Ord (GHC.Arr.Array i e)
-- Defined in ‘GHC.Arr’
...plus 26 others
In the second argument of ‘($)’, namely ‘foo []’
In the expression: null $ foo []
In an equation for ‘test2’: test2 = null $ foo []
The problem is in the expression test2 = null $ foo []. Furthermore, removing Ord a constraint from the type definition of foo will solve the problem. Strangely, typing null $ foo [] in the interactive mode (after loading the definition for foo) works correctly and produces the expected true.
I need a clear explanation for this behaviour.
I like thinking of typeclasses in "dictionary-passing style". The signature
foo :: Ord a => [a] -> [a]
says that foo takes a dictionary of methods for Ord a, essentially as a parameter, and a list of as, and gives back a list of as. The dictionary has things in it like (<) :: a -> a -> Bool and its cousins. When we call foo, we need to supply such a dictionary. This is done implicitly by the compiler. So
foo [1,2,3]
will use the Ord Integer dictionary, because we know that a is Integer.
However, in foo [], the list could be a list of anything -- there is no information to determine the type. But we still need to find the Ord dictionary to pass to foo (although your foo doesn't use it at all, the signature says that it could, and that's all that matters). That's why there is an ambiguous type error. You can specify the type manually, which will give enough information to fill in the dictionary, like this
null (foo ([] :: [Integer]))
or with the new TypeApplications extension
null (foo #Integer [])
If you remove the Ord constraint, it works, as you have observed, and this is just because we no longer need to supply a dictionary. We don't need to know what specific type a is to call foo anymore (this feels a little magical to me :-).
Note that foo ([] :: Ord a => [a]) does not eliminate the ambiguity, because it is not known which specific Ord dictionary you want to pass; is it Ord Int or Ord (Maybe String), etc.? There is no generic Ord dictionary, so we have to choose, and there is no rule for what type to choose in this case. Whereas when you say (Ord a, Num a) => [a], then defaulting specifies a way to choose, and we pick Integer, since it is a special case of the Num class.
The fact that foo [] works in ghci is due to ghci’s extended defaulting rules. It might be worth reading about type defaulting in general, which is surely not the prettiest part of Haskell, but it is going to come up a lot in the kinds of corner cases you are asking about.

Can I parameterise the empty constraint type?

I have a class for queues which allows the instance to define the constraints it places on the elements. For example, a priority queue requires its elements to be orderable:
{-# LANGUAGE MultiParamTypeClasses, ConstraintKinds, FunctionalDependencies #-}
class Queue q c | q -> c where
empty :: q a
qpop :: c a => q a -> Maybe (a, q a)
qpush :: c a => a -> q a -> q a
data PriorityQueue a = ...
instance Queue PriorityQueue Ord where
...
This works a charm: inside the instance declaration for PriorityQueue I can operate on elements of the queue using members of Ord such as (>).
I've got stuck trying to define a queue which places no requirements on its elements:
newtype LIFO a = LIFO [a]
instance Queue LIFO () where
empty = LIFO []
qpop (LIFO []) = Nothing
qpop (LIFO (x:xs)) = Just (x, LIFO xs)
qpush x (LIFO xs) = LIFO $ x:xs
This fails, with the following error message from GHC:
The second argument of `Queue' should have kind `* -> Constraint',
but `()' has kind `*'
In the instance declaration for `Queue LIFO ()'
This error message makes sense to me. Eq accepts a type parameter (we typically write Eq a => ...) whereas () has no parameters - it's a plain old kind mismatch.
I had a crack at writing a type function which ignores its second argument, which would allow me to write instance Queue LIFO (Const ()):
{-# LANGUAGE TypeFamilies, KindSignatures, PolyKinds #-}
type family Const a b :: k -> k2 -> k
type instance Const a b = a
I find this interaction of type families and kind polymorphism quite beautiful, so I was rather disappointed when it didn't work (I really thought it would!):
Expecting two more arguments to `a'
The first argument of `Const' should have kind `*',
but `a' has kind `k0 -> k1 -> k0'
In the type `a'
In the type instance declaration for `Const'
I have a feeling this last example is something stupid like a syntax mistake (I'm new to type families). How can I write a Constraint which doesn't place any restrictions on its argument?
This should work:
class NoConstraint a where
instance NoConstraint a where
instance Queue LIFO NoConstraint where
...
The above defines a constraint which is satisfied by all types. As such, the obligations c a where c = NoConstraint can always be discharged.
Also, since there are no members in that class, it should have zero (or nearly zero) run-time cost.
The "constraint" () you are trying to use is not seen as an empty constraint set by GHC, but as the unit type () :: *. This causes Const () :: k2 -> *, which triggers the kind error.
If you do not want to use a custom class, you might try e.g. Const (Eq ()) or Const (Num Int), which have the right kind k2 -> Constraint. I do not recommend this, though, since I find it less readable than using a custom class.
(This requires to enable some extensions, as Benjamin Hodgson points out below in a comment.)

Typeclass instance with functional dependencies doesn't work

Playing around with type-classes I came up with the seemingly innocent
class Pair p a | p -> a where
one :: p -> a
two :: p -> a
This seems to work fine, e.g.
instance Pair [a] a where
one [x,_] = x
two [_,y] = y
However I run in trouble for tuples. Even though the following definition compiles...
instance Pair (a,a) a where
one p = fst p
two p = snd p
... I can't use it as I expected:
main = print $ two (3, 4)
No instance for (Pair (t, t1) a)
arising from a use of `two' at src\Main.hs:593:15-23
Possible fix: add an instance declaration for (Pair (t, t1) a)
In the second argument of `($)', namely `two (3, 4)'
In the expression: print $ two (3, 4)
In the definition of `main': main = print $ two (3, 4)
Is there a way to define the instance correctly? Or do I have to resort to a newtype wrapper?
Your instance works just fine, actually. Observe:
main = print $ two (3 :: Int, 4 :: Int)
This works as expected. So why doesn't it work without the type annotation, then? Well, consider the tuple's type: (3, 4) :: (Num t, Num t1) => (t, t1). Because numeric literals are polymorphic, nothing requires them to be the same type. The instance is defined for (a, a), but the existence of that instance won't tell GHC to unify the types (for a variety of good reasons). Unless GHC can deduce by other means that the two types are the same, it won't choose the instance you want, even if the two types could be made equal.
To solve your problem, you could just add type annotations, as I did above. If the arguments are coming from elsewhere it's usually unnecessary because they'll already be known to be the same type, but it gets clumsy quickly if you want to use numeric literals.
An alternative solution is to note that, because of how instance selection works, having an instance for (a, a) means that you can't write an instance like (a, b) as well even if you wanted to. So we can cheat a bit, to force the unification using the type class, like this:
instance (a ~ b) => Pair (a,b) a where
That needs the TypeFamilies extension for the ~ context, I think. What this does is allow the instance to match on any tuple at first, because instance selection ignores the context. After choosing the instance, however, the a ~ b context asserts type equality, which will produce an error if they're different but--more importantly here--will unify the type variables if possible. Using this, your definition of main works as is, without annotations.
The problem is that a literal number has a polymorphic type. It is not obvious to the typechecker that both literals should have the same type (Int). If you use something that is not polymorphic for your tuples, your code should work. Consider these examples:
*Main> two (3,4)
<interactive>:1:1:
No instance for (Pair (t0, t1) a0)
arising from a use of `two'
Possible fix: add an instance declaration for (Pair (t0, t1) a0)
In the expression: two (3, 4)
In an equation for `it': it = two (3, 4)
*Main> let f = id :: Int -> Int -- Force a monomorphic type
*Main> two (f 3,f 4)
4
*Main> two ('a','b')
'b'
*Main> two ("foo","bar")
"bar"
*Main> two (('a':),('b':)) "cde"
"bcde"
*Main>

Haskell Typeclass shorthand

So, I have a pair of typeclasses that I'll be using a lot together, and I want to avoid specifying both each time. Basically, instead of putting
:: (Ord a, Fractional a, Ord b, Fractional b, ... Ord z, Fractional z) =>
at the beginning of all my type specifications, I'd rather put
:: (OrdFractional a, OrdFractional b, ... OrdFractional z)
So, my initial idea on how to do this was to just declare a new typeclass
module Example where
class (Fractional a, Ord a) => OrdFractional a
example :: (OrdFractional a, OrdFractional b) => (a,b) -> (a,b) -> (a,b) -> Bool
example (x1,y1) (x2,y2) (x3,y3) = (x1/x2 < x2/x3) && (y1/y2 < y2/y3)
But this didn't work as automagically as I wished it would:
% ghci
Prelude> :l Example.hs
Ok, modules loaded: Example.
Prelude Example> example (1::Float,3::Float) (2,2) (3,1)
<interactive>:1:0:
No instance for (OrdFractional Float)
arising from a use of `example' at <interactive>:1:0-39
Possible fix:
add an instance declaration for (OrdFractional Float)
In the expression: example (1 :: Float, 3 :: Float) (2, 2) (3, 1)
In the definition of `it':
it = example (1 :: Float, 3 :: Float) (2, 2) (3, 1)
Manually creating instances seems like a drag so, next, I thought I might try to automatically create instances:
module Example where
class OrdFractional a
instance (Fractional a, Ord a) => OrdFractional a
example :: (OrdFractional a, OrdFractional b) => (a,b) -> (a,b) -> (a,b) -> Bool
example (x1,y1) (x2,y2) (x3,y3) = (x1/x2 < x2/x3) && (y1/y2 < y2/y3)
But the compiler didn't like that:
ghc -c Example.hs
Example.hs:4:0:
Illegal instance declaration for `OrdFractional a'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are type *variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `OrdFractional a'
So is there a way I can do this?
With the ConstraintKinds extension introduced in GHC 7.4, constraints are now types of kind Constraint, so you can use ordinary type synonyms to get what you want:
{-# LANGUAGE ConstraintKinds #-}
type OrdFractional a = (Ord a, Fractional a)
What you want is a class alias. There is a proposal to add it to Haskell at http://repetae.net/recent/out/classalias.html
When the compiler says "Use -XFlexibleInstances", you should try adding
{-# LANGUAGE FlexibleInstances #-}
to the top of your source (and go read the documentation to learn what it does, of course!).
In this specific case, this will make your code work:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
Flexible instances are required in order to enable the => context on the instance head, and undecidable instances are required because the compiler, when handling an OrdFractional a context, can end adding Fractional a and Ord a to the context -- which doesn't directly help with finally determining a, and under suitably horrible circumstances, typechecking may diverge; the compiler really doesn't like that. (You probably wouldn't like it if the compiler went on forever or ran out of memory, either.)
No.
Your solution of a superclass implying the other classes is the closest to what you want that is possible in Haskell. Even though that requires manual instances of that new class it is sometimes used, for example in the rewriting library.
As CesarB mentioned class aliases do what you want (and more), but they're just a proposal that's been around for years now and have never been implemented, probably because there are numerous problems with it. Instead, various other proposals have popped up, but none of those were implemented either. (For a list of those proposals, see this Haskellwiki page.) One of the projects at Hac5 was to modify the GHC to include a small subset of class aliases called context synonyms (which do exactly what you are asking for here and nothing more), but sadly it was never finished.

Resources