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, ...)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With