In Haskell 98, contexts consist of class constraints on type variables applied to zero or more types, as in

f :: (Functor f, Num (f Int)) => f String -> f Int -> f IntIn class and instance declarations only type variables may be constrained. With the

`-98`

option,
any type may be constrained by a class, as in
g :: (C [a], D (a -> b)) => [a] -> bClasses are not limited to a single argument either (see Section 6.2.4).

In Haskell 98, instances may only be declared for
a `data` or `newtype` type constructor
applied to type variables.
With the `-98`

option, any type may be made an instance:

instance Monoid (a -> a) where ... instance Show (Tree Int) where ... instance MyClass a where ... instance C String whereThis relaxation, together with the relaxation of contexts mentioned above, makes the checking of constraints undecidable in general (because you can now code arbitrary Prolog programs using instances). To ensure that type checking terminates, Hugs imposes a limit on the depth of constraints it will check, and type checking fails if this limit is reached. You can raise the limit with the

`-c`

option,
but such a failure usually indicates that the type checker wasn't going to
terminate for the particular constraint problem you set it.Note that GHC implements a different solution, placing syntactic restrictions on instances to ensure termination, though you can also turn these off, in which case a depth limit like that in Hugs is used.

With the relaxation on the form of instances discussed in the previous section, it seems we could write

class C a where c :: a instance C (Bool,a) where ... instance C (a,Char) where ...but then in the expression

ERROR "Test.hs":4 - Overlapping instances for class "C" *** This instance : C (a,Char) *** Overlaps with : C (Bool,a) *** Common instance : C (Bool,Char)However if the

`+o`

option is set,
they are permitted when one of the types is a substitution instance of
the other (but not equivalent to it), as in
class C a where toString :: a -> String instance C [Char] where ... instance C a => C [a] where ...Now for the type

The above analysis omitted one case, where the type `t` is
a type variable, as in

f :: C a => [a] -> String f xs = toString xsWe cannot decide which instance to choose, so Hugs rejects this definition. However if the

`+O`

option is set,
this declaration is accepted, and the more general instance is selected,
even though this will be the wrong choice if Hugs used to have a `+m`

option
(for multi-instance resolution,
if Hugs was compiled with `MULTI_INST` set),
which accepted more overlapping instances by deferring the choice between them,
but it is currently broken.

Sometimes one can avoid overlapping instances.
The particular example discussed above is similar to the situation described
by the `Show` class in the `Prelude`.
However there overlapping instances are avoided by adding the method
`showList`

to the class.

In Haskell 98, type classes have a single parameter; they may be thought of as sets of types. In Hugs, they may have one or more parameters, corresponding to relations between types, e.g.

class Isomorphic a b where from :: a -> b to :: b -> a

Multiple parameter type classes often lead to ambiguity.
Functional dependencies (inspired by relational databases)
provide a partial solution,
and were introduced in
*Type Classes with Functional Dependencies*,
Mark P. Jones, In
*Proceedings of the 9th European Symposium on Programming*, LNCS vol. 1782, Springer 2000.

Functional dependencies are introduced by a vertical bar:

class MyClass a b c | a -> b whereThis says that the

class MyClass a b c | a -> b, a -> c whereThis example could also be written

class MyClass a b c | a -> b c whereSimilarly more than one type parameter may appear to the left of the arrow:

class MyClass a b c | a b -> c whereThis says that the