-- | Cleanly release resources and clean up contexts

module Control.Monad.Cleanup
  ( retry
  , always
  -- * Reexport
  , module Control.Monad.Rescue
  , module Control.Monad.Cleanup.Class
  ) where

import           Control.Monad.Cleanup.Class
import           Control.Monad.Rescue

import           Numeric.Natural

-- | Equivalent of 'finally'
always :: MonadCleanup m => m a -> m b -> m a
always :: m a -> m b -> m a
always m a
action m b
finalizer =
  m ()
-> (() -> ErrorCase m -> m b) -> (() -> m b) -> (() -> m a) -> m a
forall (m :: * -> *) resource _ig1 _ig2 a.
MonadCleanup m =>
m resource
-> (resource -> ErrorCase m -> m _ig1)
-> (resource -> m _ig2)
-> (resource -> m a)
-> m a
cleanup (() -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
          (\()
_ ErrorCase m
_ -> m b
finalizer)
          (\()
_   -> m b
finalizer)
          (\()
_   -> m a
action)

retry :: MonadCleanup m => Natural -> m a -> m a
retry :: Natural -> m a -> m a
retry Natural
0     m a
action = m a
action
retry Natural
times m a
action =
  m ()
-> (() -> ErrorCase m -> m a) -> (() -> m ()) -> (() -> m a) -> m a
forall (m :: * -> *) resource _ig1 _ig2 a.
MonadCleanup m =>
m resource
-> (resource -> ErrorCase m -> m _ig1)
-> (resource -> m _ig2)
-> (resource -> m a)
-> m a
cleanup (() -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
          (\()
_ ErrorCase m
_ -> Natural -> m a -> m a
forall (m :: * -> *) a. MonadCleanup m => Natural -> m a -> m a
retry (Natural
times Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
1) m a
action)
          (\()
_   -> () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
          (\()
_   -> m a
action)