[GHC] #7851: Give better diagnostic when arguments are omitted to a function call in do-notation

#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 | Component: Compiler (Parser) Version: 7.4.2 | Keywords: Os: MacOS X | Architecture: x86_64 (amd64) Failure: Incorrect warning at compile-time | Blockedby: Blocking: | Related: ----------------------------------------------+----------------------------- 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 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 | Component: Compiler (Parser) Version: 7.4.2 | Keywords: Os: MacOS X | Architecture: x86_64 (amd64) Failure: Incorrect warning at compile-time | Blockedby: Blocking: | Related: ----------------------------------------------+----------------------------- Comment(by JohnWiegley): The formatting was a little murdered, here is the code snippet: {{{ import Control.Monad.Trans.State main = flip runStateT 10 $ do print print "Hello" }}} -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7851#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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

#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: |
----------------------------------+-----------------------------------------
Comment(by simonpj@…):
commit 6d8d0dd94e3216ba2792f1eb9e9e086f188e1c56
{{{
Author: Simon Peyton Jones

#7851: Give better diagnostic when arguments are omitted to a function call in do- notation ------------------------------------------------+--------------------------- Reporter: JohnWiegley | Owner: Type: feature request | Status: closed Priority: normal | Milestone: Component: Compiler (Parser) | Version: 7.4.2 Resolution: fixed | Keywords: Os: MacOS X | Architecture: x86_64 (amd64) Failure: Incorrect warning at compile-time | Difficulty: Unknown Testcase: typecheck/should_fail/T7851 | Blockedby: Blocking: | Related: ------------------------------------------------+--------------------------- Changes (by simonpj): * status: new => closed * testcase: => typecheck/should_fail/T7851 * resolution: => fixed Comment: Good point. I've improved it a bit, so it does indeed now complain about too few args. This code was there all the time, but wasn't used for functions applied to ''no'' arguments; it only sprang to life if the function was applied to at least one argument. Now it works with zero arguments too. Simon -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7851#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC