Pattern synonym types should reveal their arity
I was playing around with Pattern Synonyms, when I realized that their reported type are not informative enough as they should be.
Take the following pattern synonym as an example
returns4 f | f 2 == 4 = Just f
| otherwise = Nothing
pattern Returns4 f <- (returns4 -> (Just f))
where Returns4 _ = const 4
Other than the non-data return type, there is nothing special about Returns4
.
Okay, now that we have defined Returns4
let's ask GHCi about its type.
Returns4 :: forall {a}. (Num a, Eq a) => (a -> a) -> a -> a
Okay, that seems fair.
"I" know that patterns, unlike functions, should always be saturated. So let's define a function that uses Returns4
:
testing (Returns4 f 2) = ...
testing _ = ...
Wait, why is GHC complaining that I've passed an extra argument to Returns4
?
The pattern synonym ‘Returns4’ should have 1 argument, but has been given 2
• In the pattern: Returns4 f 2
In an equation for ‘testing’:
testing (Returns4 f 2)
= ...
Because the arity of Returns4
is not reflected in its type. I.e the more intuitive type for Returns4
would be the following:
Returns4 :: forall {a}. (Num a, Eq a) => (a -> a) -> (a -> a)
It looks much better now!
Even though GHC's error message is very informative and simple, I still think it's worthwhile to enclose Non-Data function return types in parenthesis.