Commit f40023d4 authored by Petr Pudlak's avatar Petr Pudlak
Browse files

Add a utility function for retrying within MonadError



`orElse` works just as `mplus` of ResultT, but it only requires
`MonadError` and doesn't accumulate the errors, it just returns the
second one, if both actions fail.
Signed-off-by: default avatarPetr Pudlak <pudlak@google.com>
Reviewed-by: default avatarKlaus Aehlig <aehlig@google.com>
parent df478a59
...@@ -47,6 +47,7 @@ module Ganeti.BasicTypes ...@@ -47,6 +47,7 @@ module Ganeti.BasicTypes
, failError , failError
, catchErrorT , catchErrorT
, handleErrorT , handleErrorT
, orElse
, iterateOk , iterateOk
, select , select
, runListHead , runListHead
...@@ -307,6 +308,12 @@ catchErrorT :: (Monad m, Error e) ...@@ -307,6 +308,12 @@ catchErrorT :: (Monad m, Error e)
catchErrorT = flip handleErrorT catchErrorT = flip handleErrorT
{-# INLINE catchErrorT #-} {-# INLINE catchErrorT #-}
-- | If the first computation fails, run the second one.
-- Unlike 'mplus' instance for 'ResultT', this doesn't require
-- the 'Monoid' constrait.
orElse :: (MonadError e m) => m a -> m a -> m a
orElse x y = catchError x (const y)
-- | Iterate while Ok. -- | Iterate while Ok.
iterateOk :: (a -> GenericResult b a) -> a -> [a] iterateOk :: (a -> GenericResult b a) -> a -> [a]
iterateOk f a = genericResult (const []) ((:) a . iterateOk f) (f a) iterateOk f a = genericResult (const []) ((:) a . iterateOk f) (f a)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment