fix misleading error message regarding function arity
ClosedPublic

Authored by Yuras on Dec 4 2014, 7:18 PM.

Details

Summary

The error reports something like:

The function ‘f’ is applied to three arguments,
but its type ‘Int -> Float -> Char -> Bool’ has only three

The original type was "Monad m => Int -> Float -> m Bool", but
"m" was unified with "-> Char".

Now it looks better:

The function ‘f’ is applied to three arguments,
its type is ‘Int -> Float -> m0 Bool’,
it is specialized to ‘Int -> Float -> Char -> Bool’
Test Plan

T9605

Diff Detail

Repository
rGHC Glasgow Haskell Compiler
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
Yuras updated this revision to Diff 1860.Dec 4 2014, 7:18 PM
Yuras retitled this revision from to fix misleading error message regarding function arity.
Yuras updated this object.
Yuras edited the test plan for this revision. (Show Details)
Yuras added reviewers: austin, simonpj.
Yuras updated the Trac tickets for this revision.
austin requested changes to this revision.Dec 5 2014, 2:24 PM
austin edited edge metadata.

Hm, perhaps a slight modification to the wording:

The function ‘f’ is applied to three arguments,
but its inferred type is ‘Int -> Float -> Char -> Bool’

That is, just add the but and the is.

This revision now requires changes to proceed.Dec 5 2014, 2:24 PM
Yuras added a comment.Dec 6 2014, 4:59 AM

@austin are you sure but is necessary here? It suggests that there is a mismatch between number of arguments and function arity, but that is not true. This two lines provide an additional context in case the inferred is specialized in unexpected way, e.g. when user missed do or parenthesis.

Yuras added a comment.Dec 6 2014, 6:39 AM

@austin what about the next:

Couldn't match type ‘m Bool’ with ‘Bool’
Expected type: Char -> m Bool
  Actual type: Char -> Bool
Relevant bindings include f1 :: m Bool (bound at test.hs:3:1)
The function ‘f2’ is applied to three arguments,
its type is ‘Int -> Float -> m0 Bool’,
specialized to ‘Int -> Float -> Char -> Bool’
In the expression: f2 0 0 'a'
In an equation for ‘f1’: f1 = f2 0 0 'a'

Here I replaced "inferred" with "specialized" and added the original type.

I found it pretty good in more complex cases (see Trac #9605):

Couldn't match type ‘String
                     -> Control.Monad.Trans.RWS.Lazy.RWST
                          () [String] () Data.Functor.Identity.Identity ()’
              with ‘()’
Expected type: Int
               -> String
               -> Control.Monad.Trans.RWS.Lazy.RWST
                    () [String] () Data.Functor.Identity.Identity ()
  Actual type: Int -> ()
The function ‘\ l -> tell [l]’ is applied to two arguments,
its type is ‘t0 -> m0 ()’,
specialized to ‘(Int -> RWS () [String] () ()) -> Int -> ()’
In the second argument of ‘(>>=)’, namely ‘(\ l -> tell [l]) go i’
In the expression: return (show i) >>= (\ l -> tell [l]) go i
Yuras updated this revision to Diff 1884.Dec 7 2014, 6:52 AM
Yuras edited edge metadata.

add both the original and specialized types into error context

Yuras updated this revision to Diff 1885.Dec 7 2014, 6:57 AM
Yuras edited edge metadata.

update test output

austin accepted this revision.Dec 8 2014, 9:48 AM
austin edited edge metadata.

Yes, I think I like this more. Thank you Yuras!

This revision is now accepted and ready to land.Dec 8 2014, 9:48 AM
Yuras updated this object.Dec 8 2014, 4:07 PM
Yuras edited edge metadata.
Yuras updated this object.
austin updated this object.Dec 9 2014, 6:11 PM
This revision was automatically updated to reflect the committed changes.