Question

I have some code that looks like this:

retryOnTimeout :: IO a -> IO a
retryOnTimeout action = catch action $ \ResponseTimeout -> 
                            do putStrLn "Timed out. Trying again."
                               threadDelay 5000000
                               action 

The problem is that there are a lot of other constructors of HttpException, and I would like to generally keep trying again, regardless of exactly what the error is. Now if I replace ResponseTimeout with _ then I will get a compile error because it cannot deduce the type of the exception.

I don't really want to provide a type signature for the exception handler either.

I know it's not much duplication, but adding a case for _ feels wrong because it's like saying: if the exception is ResponseTimeout then do x, but if the exception is anything else do exactly the same thing. Is there a concise way to use a wildcard but still let the compiler know which type it is?

Was it helpful?

Solution

If you don't care about the exception value it's totally fine to use _ but you'll need to use ScopedTypeVariables or a let clause to specify the type you want.

{-# LANGUAGE ScopedTypeVariables #-}

retryOnTimeout :: IO a -> IO a
retryOnTimeout action = catch action $ \ (_ :: HttpException) -> do
  putStrLn "Timed out. Trying again."
  threadDelay 5000000
  action
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top