Outer bound type declarations without ScopedTypeVariables
haskell
Solution
If you want to avoid `ScopedTypeVariables`, you can most of the time use `asTypeOf`.
retrying [] action = action
retrying (i:is) action = catch action processError
where
processError e = snd (e `asTypeOf` (undefined :: IOException), threadDelay i >> retrying is action)
The `undefined :: IOException` is an expression type signature, and that is allowed by the standard. The `asTypeOf` requires the exception `e` to be an `IOException`.
I would prefer `ScopedTypeVariables` here, though.
With
retrying :: [Int] -> IO a -> IO a
the type of `processError` is inferred as
processError :: IOException -> IO a
with the `a` here being the same type variable as in the signature of `retrying`. That type can, however, not be specified in Haskell without the `ScopedTypeVariables` extension, since type variables in written-down signatures are by default universally quantified.
Problem
I have a following working definition: ``` {-# LANGUAGE ScopedTypeVariables #-} module Control.Retry where import Prelude hiding (catch) import Control.Exception import Control.Concurrent retrying [] action = action retrying (i:is) action = catch action processError where processError (e :: IOException) = threadDelay i >> retrying is action ``` Just out of curiosity I am wondering how I could reimplement this without utilizing the `ScopedTypeVariables` pragma, or whether I could at all, and what the inferred type declaration of `processError` actually is, because specifying `processError :: IOException -> IO a` makes it uncompilable.