Typed holes' "valid substitutions" suggestions are oblivious to type class constraints
This example is taken from Chris Allen's blog post here:
pleaseShow :: Show a => Bool -> a -> Maybe String
pleaseShow False _ = Nothing
pleaseShow True a = Just (show _a)
On a recent GHC HEAD build, compiling this outputs:
Bug.hs:3:32: error:
• Found hole: _a :: a0
Where: ‘a0’ is an ambiguous type variable
Or perhaps ‘_a’ is mis-spelled, or not in scope
• In the first argument of ‘show’, namely ‘_a’
In the first argument of ‘Just’, namely ‘(show _a)’
In the expression: Just (show _a)
• Relevant bindings include
a :: a (bound at Bug.hs:3:17)
pleaseShow :: Bool -> a -> Maybe String (bound at Bug.hs:2:1)
Valid substitutions include
(++) :: forall a. [a] -> [a] -> [a]
(imported from ‘Prelude’ at Bug.hs:1:1
(and originally defined in ‘GHC.Base’))
fail :: forall (m :: * -> *). Monad m => forall a. String -> m a
(imported from ‘Prelude’ at Bug.hs:1:1
(and originally defined in ‘GHC.Base’))
return :: forall (m :: * -> *). Monad m => forall a. a -> m a
(imported from ‘Prelude’ at Bug.hs:1:1
(and originally defined in ‘GHC.Base’))
errorWithoutStackTrace :: forall (a :: TYPE r). [Char] -> a
(imported from ‘Prelude’ at Bug.hs:1:1
(and originally defined in ‘GHC.Err’))
seq :: forall a b. a -> b -> b
(imported from ‘Prelude’ at Bug.hs:1:1
(and originally defined in ‘GHC.Prim’))
(<>) :: forall a. Semigroup a => a -> a -> a
(imported from ‘Prelude’ at Bug.hs:1:1
(and originally defined in ‘GHC.Base’))
(Some substitutions suppressed; use -fmax-valid-substitutions=N or -fno-max-valid-substitutions)
|
3 | pleaseShow True a = Just (show _a)
| ^^
There are a couple very unsavory things about this error:
- GHC makes no attempt to inform me that
a0
is aShow
instance! This is the primary gripe in the blog post, and it's worth emphasizing, since without theShow
constraint,a0
just looks like any other random type variable. Speaking of which... - The list of valid substitutions is incorrect! It suggests several things which have function types, such as
(++)
andfail
, but(->)
does not have aShow
instance! This list ought to be pruned based on the current type class constraints in scope.
Trac metadata
Trac field | Value |
---|---|
Version | 8.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (Type checker) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |