
#14273: Typed holes are oblivious to type class constraints -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 (Type checker) | Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: Poor/confusing Unknown/Multiple | error message Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- This example is taken from Chris Allen's blog post [http://bitemyapp.com//posts/2017-09-23-please-stop-using-typed-holes.html here]: {{{#!hs 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: 1. GHC makes no attempt to inform me that `a0` is a `Show` instance! This is the primary gripe in the blog post, and it's worth emphasizing, since without the `Show` constraint, `a0` just looks like any other random type variable. Speaking of which... 2. The list of valid substitutions is incorrect! It suggests several things which have function types, such as `(++)` and `fail`, but `(->)` does not have a `Show` instance! This list ought to be pruned based on the current type class constraints in scope. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14273 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler