
I'm probably doing something wrong but this example doesn't compile for me under ghc 6.10.1 (http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception...):
catch (openFile f ReadMode) (\e -> hPutStr stderr ("Couldn't open "++f++": " ++ show e))
Run.hs:77:24: Couldn't match expected type `Handle' against inferred type `()' Expected type: IO Handle Inferred type: IO () In the expression: hPutStr stderr ("Couldn't open " ++ d ++ ": " ++ show e) In the second argument of `CE.catch', namely `(\ e -> hPutStr stderr ("Couldn't open " ++ d ++ ": " ++ show e))'
Fair enough because openFile returns a Handle and hPutStr returns () so they don't match as the compiler says.
CE.catch :: (CE.Exception e) => IO a -> (e -> IO a) -> IO a
So if I fix the example thus:
foo d = CE.catch (openFile d ReadMode >> return ()) (\e -> hPutStr stderr ("Couldn't open "++ d ++": " ++ show e))
I get
Run.hs:70:8: Ambiguous type variable `e' in the constraint: `CE.Exception e' arising from a use of `CE.catch' at Run.hs:(70,8)-(71,78) Probable fix: add a type signature that fixes these type variable(s)
Now I think I never used to get this under 6.8.2 but I don't easily have a 6.8.2 to try it out on. Doing what the compiler suggests doesn't work for obvious reasons:
foo :: CE.Exception e => FilePath -> IO () foo d = CE.catch (openFile d ReadMode >> return ()) (\e -> hPutStr stderr ("Couldn't open "++ d ++": " ++ show e))
Run.hs:69:0: Ambiguous constraint `CE.Exception e' At least one of the forall'd type variables mentioned by the constraint must be reachable from the type after the '=>' In the type signature for `foo': foo :: (CE.Exception e) => FilePath -> IO ()
There seems to be a ticket for it (http://hackage.haskell.org/trac/ghc/ticket/2819) but this doesn't give a suggested example that compiles. Dominic.