
I've long wondered why GHC issues such prolix error messages when it runs into a problem. Here's a representative example from some hacking I'm currently doing: src/Network/Hackage/CabalPackage/Setup.hs:68:5: Couldn't match expected type `(RpmFlags, [String])' against inferred type `()' Expected type: IO (RpmFlags, [String]) Inferred type: IO () In the expression: (when (not (null unknown))) $ (do hPutStrLn stderr "Unrecognised options:" mapM_ (hPutStrLn stderr) unknown exitWith (ExitFailure 1)) This might not look like a terribly long error, but that's because I've snipped a bunch of context that GHC also prints: In the expression: do let (os, args', unknown, errs) = getOpt' RequireOrder options args opts = foldl (flip ($)) emptyRpmFlags os (when (rpmHelp opts)) $ (do printHelp stdout exitWith ExitSuccess) (when (not (null errs))) $ (do hPutStrLn stderr "Errors:" mapM_ (hPutStrLn stderr) errs exitWith (ExitFailure 1)) (when (not (null unknown))) $ (do hPutStrLn stderr "Unrecognised options:" mapM_ (hPutStrLn stderr) unknown exitWith (ExitFailure 1)) This length is on the modest side for a block of monadic code. With a longer chunk of code, individual error messages can easily stretch to dozens of lines long, due purely to GHC printing context information that amounts to repeating my source code back at me. I don't understand the motivation behind this verbosity. Clearly, a little bit of context is helpful, so I can see which expression GHC is objecting to, but why repeat the entire surrounding chunk of code back at me, when I already have the file name and line number, and the original code that caused the error? Compilers for other languages seem content with as little as one line of output per error (which I am not advocating), or a few lines of source with the problem highlighted, but I rarely see more. Hugs also tends towards the terse side, but I've never found this to be a problem. Cheers,