{-# LANGUAGE TemplateHaskell #-}
module Polysemy.Resource
(
Resource (..)
, bracket
, bracket_
, bracketOnError
, finally
, onException
, runResource
, resourceToIOFinal
) where
import qualified Control.Exception as X
import Polysemy
import Polysemy.Final
data Resource m a where
Bracket
:: m a
-> (a -> m c)
-> (a -> m b)
-> Resource m b
BracketOnError
:: m a
-> (a -> m c)
-> (a -> m b)
-> Resource m b
makeSem ''Resource
bracket_
:: Member Resource r
=> Sem r a
-> Sem r b
-> Sem r c
-> Sem r c
bracket_ :: forall (r :: EffectRow) a b c.
Member Resource r =>
Sem r a -> Sem r b -> Sem r c -> Sem r c
bracket_ Sem r a
begin Sem r b
end Sem r c
act = forall (r :: EffectRow) a c b.
Member Resource r =>
Sem r a -> (a -> Sem r c) -> (a -> Sem r b) -> Sem r b
bracket Sem r a
begin (forall a b. a -> b -> a
const Sem r b
end) (forall a b. a -> b -> a
const Sem r c
act)
finally
:: Member Resource r
=> Sem r a
-> Sem r b
-> Sem r a
finally :: forall (r :: EffectRow) a b.
Member Resource r =>
Sem r a -> Sem r b -> Sem r a
finally Sem r a
act Sem r b
end = forall (r :: EffectRow) a c b.
Member Resource r =>
Sem r a -> (a -> Sem r c) -> (a -> Sem r b) -> Sem r b
bracket (forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (forall a b. a -> b -> a
const Sem r b
end) (forall a b. a -> b -> a
const Sem r a
act)
onException
:: Member Resource r
=> Sem r a
-> Sem r b
-> Sem r a
onException :: forall (r :: EffectRow) a b.
Member Resource r =>
Sem r a -> Sem r b -> Sem r a
onException Sem r a
act Sem r b
end = forall (r :: EffectRow) a c b.
Member Resource r =>
Sem r a -> (a -> Sem r c) -> (a -> Sem r b) -> Sem r b
bracketOnError (forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (forall a b. a -> b -> a
const Sem r b
end) (forall a b. a -> b -> a
const Sem r a
act)
resourceToIOFinal :: Member (Final IO) r
=> Sem (Resource ': r) a
-> Sem r a
resourceToIOFinal :: forall (r :: EffectRow) a.
Member (Final IO) r =>
Sem (Resource : r) a -> Sem r a
resourceToIOFinal = forall (m :: * -> *) (e :: Effect) (r :: EffectRow) a.
Member (Final m) r =>
(forall x (rInitial :: EffectRow).
e (Sem rInitial) x -> Strategic m (Sem rInitial) x)
-> Sem (e : r) a -> Sem r a
interpretFinal forall a b. (a -> b) -> a -> b
$ \case
Bracket Sem rInitial a
alloc a -> Sem rInitial c
dealloc a -> Sem rInitial x
use -> do
IO (f a)
a <- forall (n :: * -> *) a (m :: * -> *) (f :: * -> *).
n a -> Sem (WithStrategy m f n) (m (f a))
runS Sem rInitial a
alloc
f a -> IO (f c)
d <- forall a (n :: * -> *) b (m :: * -> *) (f :: * -> *).
(a -> n b) -> Sem (WithStrategy m f n) (f a -> m (f b))
bindS a -> Sem rInitial c
dealloc
f a -> IO (f x)
u <- forall a (n :: * -> *) b (m :: * -> *) (f :: * -> *).
(a -> n b) -> Sem (WithStrategy m f n) (f a -> m (f b))
bindS a -> Sem rInitial x
use
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
X.bracket IO (f a)
a f a -> IO (f c)
d f a -> IO (f x)
u
BracketOnError Sem rInitial a
alloc a -> Sem rInitial c
dealloc a -> Sem rInitial x
use -> do
Inspector f
ins <- forall (m :: * -> *) (f :: * -> *) (n :: * -> *).
Sem (WithStrategy m f n) (Inspector f)
getInspectorS
IO (f a)
a <- forall (n :: * -> *) a (m :: * -> *) (f :: * -> *).
n a -> Sem (WithStrategy m f n) (m (f a))
runS Sem rInitial a
alloc
f a -> IO (f c)
d <- forall a (n :: * -> *) b (m :: * -> *) (f :: * -> *).
(a -> n b) -> Sem (WithStrategy m f n) (f a -> m (f b))
bindS a -> Sem rInitial c
dealloc
f a -> IO (f x)
u <- forall a (n :: * -> *) b (m :: * -> *) (f :: * -> *).
(a -> n b) -> Sem (WithStrategy m f n) (f a -> m (f b))
bindS a -> Sem rInitial x
use
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
X.bracketOnError
IO (f a)
a
f a -> IO (f c)
d
(\f a
x -> do
f x
result <- f a -> IO (f x)
u f a
x
case forall (f :: * -> *). Inspector f -> forall x. f x -> Maybe x
inspect Inspector f
ins f x
result of
Just x
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure f x
result
Maybe x
Nothing -> do
f c
_ <- f a -> IO (f c)
d f a
x
forall (f :: * -> *) a. Applicative f => a -> f a
pure f x
result
)
{-# INLINE resourceToIOFinal #-}
runResource
:: ∀ r a
. Sem (Resource ': r) a
-> Sem r a
runResource :: forall (r :: EffectRow) a. Sem (Resource : r) a -> Sem r a
runResource = forall (e :: Effect) (r :: EffectRow) a.
(forall (rInitial :: EffectRow) x.
e (Sem rInitial) x -> Tactical e (Sem rInitial) r x)
-> Sem (e : r) a -> Sem r a
interpretH forall a b. (a -> b) -> a -> b
$ \case
Bracket Sem rInitial a
alloc a -> Sem rInitial c
dealloc a -> Sem rInitial x
use -> do
Sem (Resource : r) (f a)
a <- forall (m :: * -> *) a (e :: Effect) (f :: * -> *)
(r :: EffectRow).
m a -> Sem (WithTactics e f m r) (Sem (e : r) (f a))
runT Sem rInitial a
alloc
f a -> Sem (Resource : r) (f c)
d <- forall a (m :: * -> *) b (e :: Effect) (f :: * -> *)
(r :: EffectRow).
(a -> m b) -> Sem (WithTactics e f m r) (f a -> Sem (e : r) (f b))
bindT a -> Sem rInitial c
dealloc
f a -> Sem (Resource : r) (f x)
u <- forall a (m :: * -> *) b (e :: Effect) (f :: * -> *)
(r :: EffectRow).
(a -> m b) -> Sem (WithTactics e f m r) (f a -> Sem (e : r) (f b))
bindT a -> Sem rInitial x
use
let run_it :: Sem (Resource : r) a -> Sem (e : r) a
run_it = forall (e :: Effect) (r :: EffectRow) a. Sem r a -> Sem (e : r) a
raise forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: EffectRow) a. Sem (Resource : r) a -> Sem r a
runResource
f a
resource <- forall {r :: EffectRow} {a} {e :: Effect}.
Sem (Resource : r) a -> Sem (e : r) a
run_it Sem (Resource : r) (f a)
a
f x
result <- forall {r :: EffectRow} {a} {e :: Effect}.
Sem (Resource : r) a -> Sem (e : r) a
run_it forall a b. (a -> b) -> a -> b
$ f a -> Sem (Resource : r) (f x)
u f a
resource
f c
_ <- forall {r :: EffectRow} {a} {e :: Effect}.
Sem (Resource : r) a -> Sem (e : r) a
run_it forall a b. (a -> b) -> a -> b
$ f a -> Sem (Resource : r) (f c)
d f a
resource
forall (f :: * -> *) a. Applicative f => a -> f a
pure f x
result
BracketOnError Sem rInitial a
alloc a -> Sem rInitial c
dealloc a -> Sem rInitial x
use -> do
Sem (Resource : r) (f a)
a <- forall (m :: * -> *) a (e :: Effect) (f :: * -> *)
(r :: EffectRow).
m a -> Sem (WithTactics e f m r) (Sem (e : r) (f a))
runT Sem rInitial a
alloc
f a -> Sem (Resource : r) (f c)
d <- forall a (m :: * -> *) b (e :: Effect) (f :: * -> *)
(r :: EffectRow).
(a -> m b) -> Sem (WithTactics e f m r) (f a -> Sem (e : r) (f b))
bindT a -> Sem rInitial c
dealloc
f a -> Sem (Resource : r) (f x)
u <- forall a (m :: * -> *) b (e :: Effect) (f :: * -> *)
(r :: EffectRow).
(a -> m b) -> Sem (WithTactics e f m r) (f a -> Sem (e : r) (f b))
bindT a -> Sem rInitial x
use
let run_it :: Sem (Resource : r) a -> Sem (e : r) a
run_it = forall (e :: Effect) (r :: EffectRow) a. Sem r a -> Sem (e : r) a
raise forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: EffectRow) a. Sem (Resource : r) a -> Sem r a
runResource
f a
resource <- forall {r :: EffectRow} {a} {e :: Effect}.
Sem (Resource : r) a -> Sem (e : r) a
run_it Sem (Resource : r) (f a)
a
f x
result <- forall {r :: EffectRow} {a} {e :: Effect}.
Sem (Resource : r) a -> Sem (e : r) a
run_it forall a b. (a -> b) -> a -> b
$ f a -> Sem (Resource : r) (f x)
u f a
resource
Inspector f
ins <- forall (e :: Effect) (f :: * -> *) (m :: * -> *) (r :: EffectRow).
Sem (WithTactics e f m r) (Inspector f)
getInspectorT
case forall (f :: * -> *). Inspector f -> forall x. f x -> Maybe x
inspect Inspector f
ins f x
result of
Just x
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure f x
result
Maybe x
Nothing -> do
f c
_ <- forall {r :: EffectRow} {a} {e :: Effect}.
Sem (Resource : r) a -> Sem (e : r) a
run_it forall a b. (a -> b) -> a -> b
$ f a -> Sem (Resource : r) (f c)
d f a
resource
forall (f :: * -> *) a. Applicative f => a -> f a
pure f x
result
{-# INLINE runResource #-}