{-# options_haddock prune #-}

-- |Description: Mask Interpreters, Internal
module Polysemy.Conc.Interpreter.Mask where

import qualified Control.Exception as Base
import Polysemy.Final (runS, withStrategicToFinal, withWeavingToFinal)

import Polysemy.Conc.Effect.Mask (
  Mask,
  Restoration (Restoration),
  RestoreMask (Restore),
  UninterruptibleMask,
  )
import Polysemy.Scoped (interpretScopedH, runScoped)

mask ::
  Member (Final IO) r =>
  (Restoration -> Sem r a) ->
  Sem r a
mask :: forall (r :: EffectRow) a.
Member (Final IO) r =>
(Restoration -> Sem r a) -> Sem r a
mask Restoration -> Sem r a
f =
  forall (m :: * -> *) (r :: EffectRow) a.
Member (Final m) r =>
ThroughWeavingToFinal m (Sem r) a -> Sem r a
withWeavingToFinal @IO \ f ()
s forall x. f (Sem r x) -> IO (f x)
lower forall x. f x -> Maybe x
_ ->
    ((forall a. IO a -> IO a) -> IO (f a)) -> IO (f a)
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
Base.mask \ forall a. IO a -> IO a
restore -> f (Sem r a) -> IO (f a)
forall x. f (Sem r x) -> IO (f x)
lower (Restoration -> Sem r a
f ((forall a. IO a -> IO a) -> Restoration
Restoration forall a. IO a -> IO a
restore) Sem r a -> f () -> f (Sem r a)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ f ()
s)

uninterruptibleMask ::
  Member (Final IO) r =>
  (Restoration -> Sem r a) ->
  Sem r a
uninterruptibleMask :: forall (r :: EffectRow) a.
Member (Final IO) r =>
(Restoration -> Sem r a) -> Sem r a
uninterruptibleMask Restoration -> Sem r a
f =
  forall (m :: * -> *) (r :: EffectRow) a.
Member (Final m) r =>
ThroughWeavingToFinal m (Sem r) a -> Sem r a
withWeavingToFinal @IO \ f ()
s forall x. f (Sem r x) -> IO (f x)
lower forall x. f x -> Maybe x
_ ->
    ((forall a. IO a -> IO a) -> IO (f a)) -> IO (f a)
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
Base.uninterruptibleMask \ forall a. IO a -> IO a
restore -> f (Sem r a) -> IO (f a)
forall x. f (Sem r x) -> IO (f x)
lower (Restoration -> Sem r a
f ((forall a. IO a -> IO a) -> Restoration
Restoration forall a. IO a -> IO a
restore) Sem r a -> f () -> f (Sem r a)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ f ()
s)

interpretRestoreMask ::
   r .
  Member (Final IO) r =>
  Restoration ->
  InterpreterFor RestoreMask r
interpretRestoreMask :: forall (r :: EffectRow).
Member (Final IO) r =>
Restoration -> InterpreterFor RestoreMask r
interpretRestoreMask (Restoration forall a. IO a -> IO a
restore) =
  (forall (rInitial :: EffectRow) x.
 RestoreMask (Sem rInitial) x
 -> Tactical RestoreMask (Sem rInitial) r x)
-> Sem (RestoreMask : r) a -> Sem r a
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 \case
    Restore Sem rInitial x
ma ->
      Strategic
  IO (Sem (WithTactics RestoreMask f (Sem rInitial) r)) (f x)
-> Sem (WithTactics RestoreMask f (Sem rInitial) r) (f x)
forall (m :: * -> *) (r :: EffectRow) a.
Member (Final m) r =>
Strategic m (Sem r) a -> Sem r a
withStrategicToFinal (IO (f (f x)) -> IO (f (f x))
forall a. IO a -> IO a
restore (IO (f (f x)) -> IO (f (f x)))
-> Sem
     (WithStrategy
        IO f (Sem (WithTactics RestoreMask f (Sem rInitial) r)))
     (IO (f (f x)))
-> Sem
     (WithStrategy
        IO f (Sem (WithTactics RestoreMask f (Sem rInitial) r)))
     (IO (f (f x)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sem (WithTactics RestoreMask f (Sem rInitial) r) (f x)
-> Sem
     (WithStrategy
        IO f (Sem (WithTactics RestoreMask f (Sem rInitial) r)))
     (IO (f (f x)))
forall (n :: * -> *) a (m :: * -> *) (f :: * -> *).
n a -> Sem (WithStrategy m f n) (m (f a))
runS (Sem rInitial x -> Tactical RestoreMask (Sem rInitial) r x
forall (m :: * -> *) a (e :: Effect) (r :: EffectRow).
m a -> Tactical e m r a
runTSimple Sem rInitial x
ma))

-- |Interpret 'Mask' by sequencing the action without masking.
interpretMaskPure :: InterpreterFor Mask r
interpretMaskPure :: forall (r :: EffectRow). InterpreterFor Mask r
interpretMaskPure =
  (forall (q :: Effect) x.
 () -> (() -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: Effect) (r0 :: EffectRow) x.
    ()
    -> RestoreMask (Sem r0) x
    -> Tactical RestoreMask (Sem r0) (Opaque q : r) x)
-> InterpreterFor Mask r
forall resource param (effect :: Effect) (r :: EffectRow).
(forall (q :: Effect) x.
 param
 -> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: Effect) (r0 :: EffectRow) x.
    resource
    -> effect (Sem r0) x -> Tactical effect (Sem r0) (Opaque q : r) x)
-> InterpreterFor (Scoped param effect) r
interpretScopedH (((() -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> () -> (() -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x
forall a b. a -> b -> a
const ((() -> Sem (Opaque q : r) x) -> () -> Sem (Opaque q : r) x
forall a b. (a -> b) -> a -> b
$ ())) \ () -> \case
    Restore Sem r0 x
ma -> Sem r0 x -> Tactical RestoreMask (Sem r0) (Opaque q : r) x
forall (m :: * -> *) a (e :: Effect) (r :: EffectRow).
m a -> Tactical e m r a
runTSimple Sem r0 x
ma

-- |Interpret 'Mask' in 'IO'.
interpretMaskFinal ::
  Member (Final IO) r =>
  InterpreterFor Mask r
interpretMaskFinal :: forall (r :: EffectRow).
Member (Final IO) r =>
InterpreterFor Mask r
interpretMaskFinal =
  (forall (q :: Effect) x.
 ()
 -> (Restoration -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: Effect).
    Restoration -> InterpreterFor RestoreMask (Opaque q : r))
-> InterpreterFor Mask r
forall resource param (effect :: Effect) (r :: EffectRow).
(forall (q :: Effect) x.
 param
 -> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: Effect).
    resource -> InterpreterFor effect (Opaque q : r))
-> InterpreterFor (Scoped param effect) r
runScoped (((Restoration -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> ()
-> (Restoration -> Sem (Opaque q : r) x)
-> Sem (Opaque q : r) x
forall a b. a -> b -> a
const (Restoration -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x
forall (r :: EffectRow) a.
Member (Final IO) r =>
(Restoration -> Sem r a) -> Sem r a
mask) \ Restoration
r -> Restoration -> InterpreterFor RestoreMask (Opaque q : r)
forall (r :: EffectRow).
Member (Final IO) r =>
Restoration -> InterpreterFor RestoreMask r
interpretRestoreMask Restoration
r

-- |Interpret 'UninterruptibleMask' by sequencing the action without masking.
interpretUninterruptibleMaskPure :: InterpreterFor UninterruptibleMask r
interpretUninterruptibleMaskPure :: forall (r :: EffectRow). InterpreterFor Mask r
interpretUninterruptibleMaskPure =
  (forall (q :: Effect) x.
 () -> (() -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: Effect) (r0 :: EffectRow) x.
    ()
    -> RestoreMask (Sem r0) x
    -> Tactical RestoreMask (Sem r0) (Opaque q : r) x)
-> InterpreterFor Mask r
forall resource param (effect :: Effect) (r :: EffectRow).
(forall (q :: Effect) x.
 param
 -> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: Effect) (r0 :: EffectRow) x.
    resource
    -> effect (Sem r0) x -> Tactical effect (Sem r0) (Opaque q : r) x)
-> InterpreterFor (Scoped param effect) r
interpretScopedH (((() -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> () -> (() -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x
forall a b. a -> b -> a
const ((() -> Sem (Opaque q : r) x) -> () -> Sem (Opaque q : r) x
forall a b. (a -> b) -> a -> b
$ ())) \ () -> \case
    Restore Sem r0 x
ma -> Sem r0 x -> Tactical RestoreMask (Sem r0) (Opaque q : r) x
forall (m :: * -> *) a (e :: Effect) (r :: EffectRow).
m a -> Tactical e m r a
runTSimple Sem r0 x
ma

-- |Interpret 'UninterruptibleMask' in 'IO'.
interpretUninterruptibleMaskFinal ::
  Member (Final IO) r =>
  InterpreterFor UninterruptibleMask r
interpretUninterruptibleMaskFinal :: forall (r :: EffectRow).
Member (Final IO) r =>
InterpreterFor Mask r
interpretUninterruptibleMaskFinal =
  (forall (q :: Effect) x.
 ()
 -> (Restoration -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: Effect).
    Restoration -> InterpreterFor RestoreMask (Opaque q : r))
-> InterpreterFor Mask r
forall resource param (effect :: Effect) (r :: EffectRow).
(forall (q :: Effect) x.
 param
 -> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: Effect).
    resource -> InterpreterFor effect (Opaque q : r))
-> InterpreterFor (Scoped param effect) r
runScoped (((Restoration -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> ()
-> (Restoration -> Sem (Opaque q : r) x)
-> Sem (Opaque q : r) x
forall a b. a -> b -> a
const (Restoration -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x
forall (r :: EffectRow) a.
Member (Final IO) r =>
(Restoration -> Sem r a) -> Sem r a
uninterruptibleMask) \ Restoration
r -> Restoration -> InterpreterFor RestoreMask (Opaque q : r)
forall (r :: EffectRow).
Member (Final IO) r =>
Restoration -> InterpreterFor RestoreMask r
interpretRestoreMask Restoration
r