[GHC] #7851: Give better diagnostic when arguments are omitted to a function call in do-notation
GHC
cvs-ghc at haskell.org
Mon Apr 22 14:52:34 CEST 2013
#7851: Give better diagnostic when arguments are omitted to a function call in do-
notation
----------------------------------+-----------------------------------------
Reporter: JohnWiegley | Owner:
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler (Parser) | Version: 7.4.2
Keywords: | Os: MacOS X
Architecture: x86_64 (amd64) | Failure: Incorrect warning at compile-time
Difficulty: Unknown | Testcase:
Blockedby: | Blocking:
Related: |
----------------------------------+-----------------------------------------
Changes (by simonpj):
* difficulty: => Unknown
Old description:
> When using any Monad other than (->) e, it is almost always an error for
> a function call to yield another function, rather than a monadic value.
> For example:
>
> import Control.Monad.Trans.State
>
> main = flip runStateT 10 $ do
> print
> print "Hello"
>
> The error you get from this code is (with GHC 7.4.2):
>
> Couldn't match expected type `StateT b0 m0 a0'
> with actual type `a1 -> IO ()'
>
> While this is fully correct, I think the compiler could do much better.
> The fact that the naked call to "print" doesn't return an IO value, but
> rather a function type, could be immediately detected as an error,
> allowing GHC to say something like:
>
> Detected function type (a -> IO ()) returned when IO () was expected,
> perhaps missing an argument in call to "print"?
>
> My example with StateT, IO and print is rather trivial, but when you
> start getting into nested monad transformers, in polymorphic functions
> where the transformer and underlying monad types are parameterized, the
> errors from GHC become downright mysterious. Only through experience
> have I become able to read them as saying "You've forgotten an argument
> in your call to f".
>
> Since I can't think of a case (outside the function monad), where
> statements within a do-notation block should yield a function type rather
> than a monadic value appropriate to that Monad, perhaps we could do
> better here in guiding the user to the real source of the problem.
New description:
When using any Monad other than `(->) e`, it is almost always an error for
a function call to yield another function, rather than a monadic value.
For example:
{{{
import Control.Monad.Trans.State
main = flip runStateT 10 $ do
print
print "Hello"
}}}
The error you get from this code is (with GHC 7.4.2):
{{{
Couldn't match expected type `StateT b0 m0 a0'
with actual type `a1 -> IO ()'
}}}
While this is fully correct, I think the compiler could do much better.
The fact that the naked call to "print" doesn't return an IO value, but
rather a function type, could be immediately detected as an error,
allowing GHC to say something like:
{{{
Detected function type (a -> IO ()) returned when IO () was expected,
perhaps missing an argument in call to "print"?
}}}
My example with `StateT`, `IO` and `print` is rather trivial, but when you
start getting into nested monad transformers, in polymorphic functions
where the transformer and underlying monad types are parameterized, the
errors from GHC become downright mysterious. Only through experience have
I become able to read them as saying "You've forgotten an argument in your
call to f".
Since I can't think of a case (outside the function monad), where
statements within a do-notation block should yield a function type rather
than a monadic value appropriate to that Monad, perhaps we could do better
here in guiding the user to the real source of the problem.
--
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7851#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list