Consider the following GHCi session:
>:set -XTypeApplications
>import Data.Map.Strict
>import GHC.Exts
>newtype MySet a = MySet (Map a ())
>let member' :: Ord a => a -> MySet a -> Bool; member' = coerce member
<interactive>:21:57: error:
* Couldn't match representation of type `a0' with that of `()'
arising from a use of `coerce'
* In the expression: coerce member
In an equation for member': member' = coerce member
>let member' :: Ord a => a -> MySet a -> Bool; member' = coerce (member @_ @())
I have a hunch of what's going on here: The type-checker needs to satisfy Coercible (Ord a => a -> Map a b -> Bool) (Ord a => a -> MySet a -> Bool) and isn't able to instantiate b in this constraint to ().
Is there a more elegant way than to do this with -XTypeApplications?
Edit: I'm especially looking for solutions that deal with many occurences of MySet a in the type, for example union :: Ord a => MySet a -> MySet a -> MySet a.
GHC needs to accept
It sees that
which leaves it needing
which leads to
But what is
b? It's ambiguous. In this case, it doesn't matter whatbis, because by parametricity,membercan't possibly care. So it would be perfectly reasonable to chooseb ~ ()and resolve the coercion trivially. But GHC generally doesn't perform such a parametricity analysis in type inference. I suspect it might be tricky to change that. Most especially, any time the type inference "guesses", there's a risk it might guess wrong and block up inference somewhere else. It's a big can of worms.As for your problem, I don't have a good solution. When you have several functions with similar patterns, you can abstract them out, but you'll still face significant annoyance.