Compiler could warn about type variable shadowing, and hint about ScopedTypeVariables
GHC already warns about variable shadowing:
$ cat test.hs module Test where timesTwoPlusOne x = timesTwo x + 1 where timesTwo x = x * 2 $ ghc -fwarn-name-shadowing test.hs ... Warning: This binding for `x' shadows the existing binding bound at <location>
However the similar warning doesn't happen for type variables.
$ cat T9244.hs module T9244 where import Control.Exception tryMaybe :: IO a -> IO (Maybe a) tryMaybe action = do result <- (try action) :: IO (Either SomeException a) return $ case result of Left _ -> Nothing Right v -> Just v $ ghc -fwarn-name-shadowing T9244.hs ... Couldn't match type `a' with `a1' `a' is a rigid type variable bound by the type signature for tryMaybe :: IO a -> IO (Maybe a) at types.hs:<line>:13 `a1' is a rigid type variable bound by an expression type signature: IO (Either SomeException a1) at types.hs:<line>:15 Expected type: IO a1 Actual type: IO a ...
Here, I thought that the 'a' in the function's type declaration was the same 'a' in the expression type declaration. However in Haskell 98, they are completely different variables.
Suggestion: if a type variable is renamed by the compiler due to a clash with another type variable, issue a warning that the second shadows the first, and give a hint about using -XScopedTypeVariables and forall.
Alternative suggestion: if an error is displayed, where the error contains a renamed type variable, issue a hint that the second shadows the first, and give a hint about using -XScopedTypeVariables and forall.