There is some confusion between the two b s:
class AsToA a where takeA :: AsToA b => a -> A -> Either A b instance AsToA b => AsToA (A -> b) where takeA fa = Right (fa)
This is not the same thing. Rename the first item to c
class AsToA a where takeA :: AsToA c => a -> A -> Either A c instance AsToA b => AsToA (A -> b) where takeA fa = Right (fa)
Right (fa) is now of type Either A b , but must be of type Either A c for any c for which AsToA c is executed. This does not check type.
The problem is that the signature
takeA :: AsToA c => a -> A -> Either A c
promises that takeA can return Either A c for any c that selects the caller. I think this is not what you want.
I'm still not sure what constitutes the real target result, but I think the problem is similar to the following.
For a function f type A->A->...->A returns a function \x -> fxx ... , with one application of x for each -> in type (hence, of type A->A ).
Possible Solution:
{-
Note that this requires OverlappingInstances , which is pretty evil. I would recommend avoiding this.
To avoid this, in this case it is enough to define an instance even for type A
{-
source share