Type classes problem: Could not deduce ...

Matthias Neubauer neubauer@informatik.uni-freiburg.de
10 Mar 2003 15:07:40 +0100


Hi Dirk,

<dirk.buehler@student.uni-tuebingen.de> writes:

> Hello, 
> 
> trying to compile the following program
> 
>   class ClassA a where
> 	foo :: a -> Int
> 
>   class ClassA a => ClassB b a where
> 	toA :: b -> a
> 
>   test :: (ClassB b a) => b -> Int
>   test x = 
> 	let y = toA x in
> 	let z = foo y in
> 	z
> 
> I get a compilation error:
> 
>   TestTypeClasses.hs:12:
>     Could not deduce (ClassB b a1) from the context (ClassB b a)
>     Probable fix:
> 	Add (ClassB b a1) to the type signature(s) for `test'
>     arising from use of `toA' at TestTypeClasses.hs:12
>     In a pattern binding: toA x
> 
> Can anybody explain the problem to me or suggest workarounds? Adding
> (ClassB b a1) to the context does not solve the problem, it just
> generates an error of the same sort.

Consider the type of the following application of toA:

*Dirk> :t toA (42::Int)
forall a. (ClassB Int a) => a

The type inference can't deduce much about the result type of the
application because type classes only specify relations over types. In
your case, ClassB is a binary relation over types. Hence, you could
easily imagine having two instances for ClassB

  instance ClassB Int Bool
  instance ClassB Int Char

putting the Int type into relation with more than a single other type.

Judging from your member function toA, I guess you'd really like to
say, that every type b of ClassB *uniquely determines* the second type
a. This can be expressed by a type class with functional
dependency[1]:

>   class ClassA a => ClassB b a | b -> a where
> 	toA :: b -> a

Cheers,

Matthias

[1] Mark P Jones, "Type Classes with Functional Dependencies", ESOP 2000

-- 
Matthias Neubauer                                       |
Universität Freiburg, Institut für Informatik           | tel +49 761 203 8060
Georges-Köhler-Allee 79, 79110 Freiburg i. Br., Germany | fax +49 761 203 8052