Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

could not deduce [instance] #530

Open
sfultong opened this issue Oct 14, 2022 · 2 comments
Open

could not deduce [instance] #530

sfultong opened this issue Oct 14, 2022 · 2 comments

Comments

@sfultong
Copy link

sfultong commented Oct 14, 2022

• Could not deduce (PrettyPrintable a)
    arising from a use of ‘cleanA’
  from the context: (Traversable f, Show s, Show1 f, Eq s, Eq1 f,
                     PrettyPrintable1 f)
    bound by the type signature for:
               sizeTerm :: forall (f :: * -> *) s.
                           (Traversable f, Show s, Show1 f, Eq s, Eq1 f,
                            PrettyPrintable1 f) =>
                           Integer
                           -> StuckExpr (SizeStuck s) (StuckUnsizedBase f)
                           -> Either
                                UnsizedRecursionToken
                                (StuckExpr (SetStuck s) (StuckAbortBase f))
    at src/Telomare/Possible.hs:(564,1)-(565,133)
  Possible fix:
    add (PrettyPrintable a) to the context of
      a type expected by the context:
        forall a.
        Base
          (EnhancedExpr
             (SplitFunctor
                (SplitFunctor
                   (SplitFunctor (SplitFunctor f UnsizedRecursionF) AbortableF)
                   SuperPositionF)
                (StuckF
                   (SetStuck (Either s StuckNeedsSizing))
                   (StuckExpr
                      (SetStuck (Either s StuckNeedsSizing))
                      (SplitFunctor
                         (SplitFunctor (SplitFunctor f UnsizedRecursionF) AbortableF)
                         SuperPositionF)))))
          a
        -> Base
             (EnhancedExpr
                (SplitFunctor
                   (StuckAbortBase f)
                   (StuckF (SetStuck s) (StuckExpr (SetStuck s) (StuckAbortBase f)))))
             a
• In the first argument of ‘hoist’, namely ‘cleanA’
  In the expression: hoist cleanA
  In an equation for ‘clean’: clean = hoist cleanA
|
663 |   clean = hoist cleanA

This seems bad to me for at least two reasons. The first is that the type variable a is only made clear in the possible fix. The second is that the possible fix is not a fix.

Original post on reddit:
https://www.reddit.com/r/haskell/comments/y40ydi/ghc_could_not_deduce_instance/

@noughtmare
Copy link

noughtmare commented Oct 15, 2022

Here's a simple standalone program that produces the same kind of error message:

{-# LANGUAGE RankNTypes #-}

f :: (forall a. a -> String) -> String
f g = g (\x -> x)

main :: IO ()
main = putStrLn $ f show

With the error message:

T.hs:6:21: error:
    • No instance for (Show a) arising from a use of ‘show’
      Possible fix:
        add (Show a) to the context of
          a type expected by the context:
            forall a. a -> String
    • In the first argument of ‘f’, namely ‘show’
      In the second argument of ‘($)’, namely ‘f show’
      In the expression: putStrLn $ f show
  |
6 | main = putStrLn $ f show
  |                     ^^^^

I agree that it would be great if the error message could mention where the type variable a comes from, so in this case it should point to the type signature of the f function.

And applying the suggested fix does not work, because the type of the function \x -> x is not an instance of Show (I chose this example intentionally for this reason). In general, I think it might be more common that this suggested fix won't work. Especially if the constraint would need to be added in another module or even another package.

So I would propose the error message to change to:

T.hs:6:21: error:
    • No instance for (Show a) arising from a use of ‘show’
         where 'a' is bound in the type signature for:
            f :: (forall a. a -> String) -> String
                         ^
  |
6 | main = putStrLn $ f show
  |                     ^^^^

And I would also change the error message for a similar error for this example:

f :: a -> String
f = show

It now gives:

T.hs:6:5: error:
    • No instance for (Show a) arising from a use of ‘show’
      Possible fix:
        add (Show a) to the context of
          the type signature for:
            f :: forall a. a -> String
    • In the expression: show
      In an equation for ‘h’: h = show
  |
6 | f = show
  |     ^^^^

I propose changing it to:

T.hs:6:5: error:
    • No instance for (Show a) arising from a use of ‘show’
         where 'a' is bound in the type signature for:
            f :: forall a. a -> String
                        ^
      Possible fix:
        add (Show a) to the type signature of 'f'
  |
6 | f = show
  |     ^^^^

Although in this case the user has not actually written forall a. so that might be confusing too.

@sfultong
Copy link
Author

Thanks for the elaboration, @noughtmare. I also prefer your proposed error messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants