Opened 5 years ago

Closed 5 years ago

Last modified 2 years ago

#9605 closed bug (fixed)

Misleading error message with forgotten "do"

Reported by: owst Owned by: Yuras
Priority: normal Milestone: 7.10.1
Component: Compiler (Type checker) Version: 7.8.3
Keywords: TypeErrorMessages Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: #7869 Differential Rev(s): Phab:D556
Wiki Page:

Description

In the following (simplified) code, I forgot to add the do keyword, when doing some refactoring. This caused GHC to give a strange error message that said approximately "The function F is applied to two arguments, but its type T has only two"... which is odd!

import Control.Monad.RWS ( evalRWS, RWS )
import Control.Monad.Writer.Class ( tell )

main = print $ evalRWS (go 1) () ()

go :: Int -> RWS () [String] () ()
go i = --Oops, forgot a do here
    return (show i) >>= (\l -> tell [l])
    -- go $ i + 1
    go i

Strangely, replacing the "go i" line with the commented-out line above it gives a sensible error message, the "Possible cause: `\l -> tell [l]' is applied to too many arguments" message, which is correct, and would've pointed me straight to the problem.

The invalid error message, which appears to be the same using GHC 7.6.3 and 7.8.3, is:

NFA.hs:8:25:
    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,
    but its type ‘(Int -> RWS () [String] () ()) -> Int -> ()’
    has only two
    In the second argument of ‘(>>=)’, namely ‘(\ l -> tell [l]) go i’
    In the expression: return (show i) >>= (\ l -> tell [l]) go i

Change History (5)

comment:1 Changed 5 years ago by Yuras

Component: CompilerCompiler (Type checker)
Differential Rev(s): D556
Owner: set to Yuras

I prepared a patch to skip "but its type T has only two" part here, and report only inferred type. Any ideas how to improve the error message further?

comment:2 Changed 5 years ago by Yuras

Differential Rev(s): D556Phab:D556

comment:3 Changed 5 years ago by Austin Seipp <austin@…>

In 09b7943321f89b945d10f8a914f4c2cbf73dff91/ghc:

fix misleading error message regarding function arity

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

Reviewers: simonpj, austin

Reviewed By: austin

Subscribers: carter, thomie

Differential Revision: https://phabricator.haskell.org/D556

GHC Trac Issues: #9605

comment:4 Changed 5 years ago by thoughtpolice

Milestone: 7.10.1
Resolution: fixed
Status: newclosed

I think the pushed revision is fine, so this is done. Thanks Yuras!

comment:5 Changed 2 years ago by simonpj

Keywords: TypeErrorMessages added
Note: See TracTickets for help on using tickets.