I changed some old code from Prelude.catch to Control.Exception.catch and got an ambiguous type error. “No big deal”, I thought. However, on closer inspection, I’m not exactly sure why this doesn’t work as-is…
handler :: Exception e => e -> IO x
with_handler :: IO x -> IO x
with_handler act = catch act handler
It appears to me that this code ought to work, and yet it clearly violates some nominative rule of the type system. (I’m not sure what though.)
Can somebody explain exactly what the type checker is unhappy about?
The compiler doesn’t know which type to use for the
handler. It can’t see at runtime what exception is raised and then choose the appropriate type forhandler, it must resolve the type at compile time.It might be possible to give
handlerthe typewhich would resolve the ambiguity.