Your problem is the scope of type variables. When you write
bar :: (Rel a b) => a -> b
bar a = aToB a :: b
The first line (the type declaration for bar
) has its own scope for type variables, and on the second line it sees the :: b
as a different b from the Rel a b
.
If you enable the ScopedTypeVariables
extension and declare your type as
bar :: forall a b. (Rel a b) => a -> b
Then the b
's scope extends over the definition of bar
.