简体   繁体   中英

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, ...)

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 ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM