module Foundation.Exception
    ( finally
    , try
    , SomeException
    ) where

import Basement.Imports
import Control.Exception (SomeException)
import Foundation.Monad.Exception

finally :: MonadBracket m => m a -> m b -> m a
finally :: m a -> m b -> m a
finally m a
f m b
g = m ()
-> (() -> a -> m a)
-> (() -> SomeException -> m b)
-> (() -> m a)
-> m a
forall (m :: * -> *) a b ignored1 ignored2.
MonadBracket m =>
m a
-> (a -> b -> m ignored1)
-> (a -> SomeException -> m ignored2)
-> (a -> m b)
-> m b
generalBracket (() -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (\() a
a -> m b
g m b -> m a -> m a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a) (\() SomeException
_ -> m b
g) (m a -> () -> m a
forall a b. a -> b -> a
const m a
f)

try :: (MonadCatch m, Exception e) => m a -> m (Either e a)
try :: m a -> m (Either e a)
try m a
a = m (Either e a) -> (e -> m (Either e a)) -> m (Either e a)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
catch (m a
a m a -> (a -> m (Either e a)) -> m (Either e a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ a
v -> Either e a -> m (Either e a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Either e a
forall a b. b -> Either a b
Right a
v)) (\e
e -> Either e a -> m (Either e a)
forall (m :: * -> *) a. Monad m => a -> m a
return (e -> Either e a
forall a b. a -> Either a b
Left e
e))