Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception warning in Haskell, but not with OldException

Why does this code work with

import qualified Control.OldException as E

but not with

import qualified Control.Exception as E

Here is the code:

    fileContents <- (readFile "shpm.txt") `E.catch` (\_ -> return "")

Here is the error I get with the "new" Exception

Ambiguous type variable `e0' in the constraint:
  (E.Exception e0) arising from a use of `E.catch'
Probable fix: add a type signature that fixes these type variable(s)
In a stmt of a 'do' block:
  fileContents <- (readFile "shpm.txt")
                  `E.catch` (\ _ -> return "No Tasks")
like image 744
Sam Stern Avatar asked Dec 26 '22 18:12

Sam Stern


2 Answers

Because the types have changed. Specifically:

  • OldException: catch :: IO a -> (Exception -> IO a) -> IO a
  • Exception: catch :: Exception e => IO a -> (e -> IO a) -> IO a

The new model needs to know what the value of e is for the Exception e type. What this means practically is that you need to tell the compiler which exception you are catching. Your example with OldException catches everything, which is now discouraged (see Catching All Exceptions for more info).

A simple fix to your function would be something like this:

foo = (readFile "foo") `E.catch` (\e -> const (return "") (e :: E.IOException))

Or the lambda-less version:

bar = (readFile "foo") `E.catch` myHandler

myHandler :: E.IOException -> IO String
myHandler _ = return ""
like image 91
Adam Wagner Avatar answered Jan 30 '23 16:01

Adam Wagner


You need to provide an explict type for the exception being caught. For example:

fileContents <- (readFile "shpm.txt") `E.catch` ((\_ -> return "") :: E.SomeException -> IO String)
like image 42
Thomas M. DuBuisson Avatar answered Jan 30 '23 14:01

Thomas M. DuBuisson