
Hi On Tue, Nov 22, 2011 at 11:03:51PM -0500, Avery Robinson wrote:
main = do m <- hGetContents stdin nums <- mapM readM . lines $ m print (sum nums) `catch` (\e -> hPutStrLn stderr ("couldn't sum lines: " ++ show e))
Using Hammar's naive do-notation desugarer [1] your example code becomes: ---8<--- main = hGetContents stdin >>= \ m -> mapM readM . lines $ m >>= \ nums -> print (sum nums) `catch` (\ e -> hPutStrLn stderr ("couldn't sum lines: " ++ show e)) --->8--- Comparing this with "ghc -ddump-ds" (cleaned up by removing _xyz suffixes and type annotations) ---8<--- Main.main = System.IO.Error.catch (>>= (GHC.IO.Handle.Text.hGetContents GHC.IO.Handle.FD.stdin) (\ m -> >>= (GHC.Base.$ (GHC.Base.. (mapM readM) Data.List.lines) m) (\ nums -> print_aAV (sum_aAU nums)))) (\ e -> System.IO.hPutStrLn GHC.IO.Handle.FD.stderr (GHC.Base.++ (GHC.Base.unpackCString# "couldn't sum lines: ") (show e))) --->8--- confirms this. But why is that? The section on do expressions of the Haskell report [2] explains that in the end a do block is just an expression. And section 3.4 [3] states that "e1 op e2 = (op) e1 e2", which in our case translates to "e1 `catch` e2 = catch e1 e2" where e1 is the preceeding do block and e2 is the lambda expression. So, the line starting with `catch` is not part of the do block any more. Greetings Alex [1] https://gist.github.com/1341505 [2] http://www.haskell.org/onlinereport/exps.html#sect3.14 [3] http://www.haskell.org/onlinereport/exps.html#sect3.4