{-# options_haddock prune #-}

-- |Description: Convenience Interpreters for all Conc Effects, Internal
module Polysemy.Conc.Interpreter.Stack where

import Polysemy.Conc.Effect.Mask (Mask, UninterruptibleMask)
import Polysemy.Conc.Effect.Race (Race)
import Polysemy.Conc.Interpreter.Mask (Restoration, interpretMaskFinal, interpretUninterruptibleMaskFinal)
import Polysemy.Conc.Interpreter.Race (interpretRace)

-- |A default basic stack with 'Final' for _polysemy-conc_.
type ConcStack =
  [
    UninterruptibleMask Restoration,
    Mask Restoration,
    Race,
    Async,
    Resource,
    Embed IO,
    Final IO
  ]

-- |Interprets 'UninterruptibleMask', 'Mask' and 'Race' in terms of @'Final' 'IO'@ and runs the entire rest of the
-- stack.
runConc ::
  Sem ConcStack a ->
  IO a
runConc :: forall a. Sem ConcStack a -> IO a
runConc =
  Sem '[Final IO] a -> IO a
forall (m :: * -> *) a. Monad m => Sem '[Final m] a -> m a
runFinal (Sem '[Final IO] a -> IO a)
-> (Sem ConcStack a -> Sem '[Final IO] a)
-> Sem ConcStack a
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
(Member (Final m) r, Functor m) =>
Sem (Embed m : r) a -> Sem r a
embedToFinal @IO (Sem '[Embed IO, Final IO] a -> Sem '[Final IO] a)
-> (Sem ConcStack a -> Sem '[Embed IO, Final IO] a)
-> Sem ConcStack a
-> Sem '[Final IO] a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem '[Resource, Embed IO, Final IO] a
-> Sem '[Embed IO, Final IO] a
forall (r :: [(* -> *) -> * -> *]) a.
Member (Final IO) r =>
Sem (Resource : r) a -> Sem r a
resourceToIOFinal (Sem '[Resource, Embed IO, Final IO] a
 -> Sem '[Embed IO, Final IO] a)
-> (Sem ConcStack a -> Sem '[Resource, Embed IO, Final IO] a)
-> Sem ConcStack a
-> Sem '[Embed IO, Final IO] a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem '[Async, Resource, Embed IO, Final IO] a
-> Sem '[Resource, Embed IO, Final IO] a
forall (r :: [(* -> *) -> * -> *]) a.
Member (Final IO) r =>
Sem (Async : r) a -> Sem r a
asyncToIOFinal (Sem '[Async, Resource, Embed IO, Final IO] a
 -> Sem '[Resource, Embed IO, Final IO] a)
-> (Sem ConcStack a
    -> Sem '[Async, Resource, Embed IO, Final IO] a)
-> Sem ConcStack a
-> Sem '[Resource, Embed IO, Final IO] a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem '[Race, Async, Resource, Embed IO, Final IO] a
-> Sem '[Async, Resource, Embed IO, Final IO] a
forall (r :: [(* -> *) -> * -> *]).
Member (Final IO) r =>
InterpreterFor Race r
interpretRace (Sem '[Race, Async, Resource, Embed IO, Final IO] a
 -> Sem '[Async, Resource, Embed IO, Final IO] a)
-> (Sem ConcStack a
    -> Sem '[Race, Async, Resource, Embed IO, Final IO] a)
-> Sem ConcStack a
-> Sem '[Async, Resource, Embed IO, Final IO] a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  '[Mask Restoration, Race, Async, Resource, Embed IO, Final IO] a
-> Sem '[Race, Async, Resource, Embed IO, Final IO] a
forall (r :: [(* -> *) -> * -> *]).
Member (Final IO) r =>
InterpreterFor (Mask Restoration) r
interpretMaskFinal (Sem
   '[Mask Restoration, Race, Async, Resource, Embed IO, Final IO] a
 -> Sem '[Race, Async, Resource, Embed IO, Final IO] a)
-> (Sem ConcStack a
    -> Sem
         '[Mask Restoration, Race, Async, Resource, Embed IO, Final IO] a)
-> Sem ConcStack a
-> Sem '[Race, Async, Resource, Embed IO, Final IO] a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem ConcStack a
-> Sem
     '[Mask Restoration, Race, Async, Resource, Embed IO, Final IO] a
forall (r :: [(* -> *) -> * -> *]).
Member (Final IO) r =>
InterpreterFor (UninterruptibleMask Restoration) r
interpretUninterruptibleMaskFinal