Type classes problem: Could not deduce ...

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. Any hints are appreciated. Cheers, dirk ______________________________________________________________________________ Werden Sie kreativ! Bei WEB.DE FreeMail heisst es jetzt nicht nur schreiben, sondern auch gestalten. http://freemail.web.de/features/?mc=021142

Hi Dirk,
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
participants (2)
-
dirk.buehler@student.uni-tuebingen.de
-
Matthias Neubauer