문제

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?

도움이 되었습니까?

해결책

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top