I am pretty sure this has been asked before, however I was unable to find the right answer:
I tried to eliminate the ambiguity in the following exemplary code snippet:
{-# LANGUAGE MultiParamTypeClasses #-}
class FooBar a b where
foo :: a -> a
foo = id
bar :: a -> a
bar = foo -- ERROR AT THIS LINE
I get an error message like so:
Ambiguous type variable `b0' in the constraint:
(FooBar a b0) arising from a use of `foo'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: foo
In an equation for `bar': bar = foo
which is understandable. Note however, that I'm actually unable to follow the compiler's advice and fix the type variable in question: foo
doesn't contain b
type variable in its type signature. Also this doesn't work:
bar = (foo :: FooBar a b => a -> a) -- ERROR, the same error message
Not even with -XScopedTypeVariables
enabled.
How to tell GHC which FooBar to use? Is it even possible?
EDIT
Following some answers: yes, I've heard about both functional dependencies and associated types.
As to functional dependencies - I am looking for a way to explicitly inform GHC which instance to use (as opposed to asking it to derive the correct type all by itself).
As to both - in the real world example that this one comes from, I actually need both of the parameters a
and b
to be independent.
Again: I know this example is extremely silly, I know b
is not used in the body of the type class, which makes no sense. This is an extreme simplification of a real world example, that actually does make sense. The real use-case involves "substitutability" of types a
using types b
and then "unifiability" of types a
and b
using types c
and unfortunately is much longer.
EDIT(2)
Okay sorry. I think you convinced me after all that I have to refactor the code in order not to have any ill-defined functions (i.e. ones that don't contain all the independent types in their type signatures). Talking to you really helped me think this thing though. Appreciated.