Reputation: 6366
With functional dependencies, I can declare the Foo
class:
class Foo a b c | a -> b where
foo1 :: a -> b -> c
foo2 :: a -> c
and when I call foo2
, everything works fine. The compiler knows which instance to use because of the dependency.
But if I remove the dependency to create Foo'
:
class Foo' a b c where
foo1' :: a -> b -> c
foo2' :: a -> c
everything still compiles fine, but now whenever I try to call foo2'
GHC throws an error about not being able to resolve which instance to use because b
is ambiguous.
Is it ever possible to call foo2'
without error? If so, how? If not, why doesn't it generate a compilation error?
Upvotes: 3
Views: 179
Reputation: 60463
It is impossible to call foo2'
in this context, because, as Daniel Fischer says, there is no way to determine which instance to use. For example, if you had:
instance Foo' Int Int Int where
foo2' x = x
instance Foo' Int Bool Int where
foo2' x = x + 1
Both of these foo2'
s have the same type signature, so there is no way to determine which one to call.
The usual way around this problem is to use a proxy:
data Proxy a = Proxy
class Foo'' a b c = where
foo2'' :: Proxy b -> a -> c
Which you use like so to select which instance:
foo'' (Proxy :: Proxy Bool) 42
Upvotes: 3