Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell type error with catch

I am playing with some online examples, and one has this phrase:

   do ... contents <- getDirectoryContents path `catch` const (return []) 

But it won't compile for me, and gives the error:

No instance for (Exception e0) arising from a use of `catch'
The type variable `e0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
  instance Exception NestedAtomically
    -- Defined in `Control.Exception.Base'
  instance Exception NoMethodError
    -- Defined in `Control.Exception.Base'
  instance Exception NonTermination
    -- Defined in `Control.Exception.Base'
  ...plus 7 others
In a stmt of a 'do' block:
  contents <- getDirectoryContents path `catch` const (return [])
In the expression:
  do { contents <- getDirectoryContents path
                   `catch` const (return []);

I had to change it to give a type for the handler, which is OK now but a bit messier:

contents <- getDirectoryContents path `catch` (\(SomeException e) -> const (return []) e)

So I am wondering why I needed to make this change, and if this is the most concise way to do it. (Yes, I know I could use alternate forms of try, handle, ...)

like image 548
guthrie Avatar asked Nov 02 '22 09:11

guthrie


1 Answers

catch has type Exception e => IO a -> (e -> IO a) -> IO a so (e -> IO a) is where you are passing the const function result but the const return type in this case is (e0 -> IO []). As you can see that this type has e0 which is not constrained like it was required in catch i.e e should have Exception instance and thats what the error says.

So conceptually, you are passing something that is "less constrained" to a place where something "more constrained" is required.

like image 151
Ankur Avatar answered Nov 08 '22 06:11

Ankur