Retry combinators for monadic actions that may fail

Version on this page:
LTS Haskell 8.2:
Stackage Nightly 2017-02-22:
Latest on Hackage:
BSD3 licensed by Ozgun Ataman
Maintained by

Module documentation for

README Build Status Coverage Status

retry - combinators for monadic actions that may fail


Monadic action combinators that add delayed-retry functionality, potentially with exponential-backoff, to arbitrary actions.

The main purpose of this package is to make it easy to work reliably with IO and similar actions that often fail. Common examples are database queries and large file uploads.


Please see haddocks for documentation.




Ozgun Ataman, Soostone Inc


Contributors, please list yourself here.

  • Mitsutoshi Aoe (@maoe)
  • John Wiegley
  • Michael Snoyman
  • Michael Xavier

Changes * Loosen HUnit dependency for tests. * Loosen QuickCheck dependency for tests.

0.7.4 * Widen transformers dependency

0.7.3 * Widen ghc-prim dependency for GHC 8

0.7.2 * Fix premature integer overflow error thanks to Mitsutoshi Aoe

0.7.1 Various documentation updates. Add stepping combinator for manual retries. Add applyPolicy and applyAndDelay Add Read instance for RetryStatus * Fix logic bug in rsPreviousDelay in first retry * Officially drop support for GHC < 7.6 due to usage of Generics.

0.7 RetryPolicy has become RetryPolicyM, allowing for policy logic to consult the monad context. RetryPolicyM now takes a RetryStatus value. Use the function rsIterNum to preserve existing behavior of RetryPolicy only receiving the number. The monadic action now gets the RetryStatus on each try. Use const if you don't need it. recoverAll explicitly does not handle the standard async exceptions. Users are encouraged to do the same when using recovering, as catching async exceptions can be hazardous. We no longer re-export (<>) from Monoid. Utility functions simulatePolicy and simulatePolicyPP have been added which help predict how a policy will behave on each iteration.


  • Actions are now retried in the original masking state, while handlers continue to run in MaskedInterruptible (@maoe)
  • Added several tests confirming exception hierarchy semantics under recovering (@ozataman)


  • Mitsutoshi's backoff work inspired a complete redo of the RetryPolicy interface, replacing it with a monoidal RetryPolicy. The result is a much thinner API that actually provides much more power to the end user.
  • Now using microseconds in all premade policies. PLEASE TAKE CARE WHEN UPGRADING. It was a bad idea to use miliseconds and deviate from norms in the first place.


  • Transitioned to using Edward Kmett's exceptions package instead of monad-control. Use 0.3 series if you still need monad-control support.


Thanks to John Wiegley and Michael Snoyman for their contributions:

  • Now using monad-control instead of MonadCatchIO, which is widely agreed to be broken.
  • Now using transformers instead of mtl, which was a broader than needed dependency.
comments powered byDisqus