{-# options_haddock prune #-}
-- |Description: Convenience Interpreters for all Conc Effects, Internal
module Polysemy.Conc.Interpreter.Stack where

import Polysemy.Async (Async, asyncToIOFinal)
import Polysemy.Resource (Resource, resourceToIOFinal)

import Polysemy.Conc.Effect.Mask (Mask, UninterruptipleMask)
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 =
  [
    UninterruptipleMask Restoration,
    Mask Restoration,
    Race,
    Async,
    Resource,
    Embed IO,
    Final IO
  ]

-- |Interprets 'UninterruptipleMask', 'Mask' and 'Race' in terms of @'Final' 'IO'@ and runs the entire rest of the
-- stack.
runConc ::
  Sem ConcStack a ->
  IO a
runConc :: 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 (r :: [(* -> *) -> * -> *]) a.
(Member (Final IO) r, Functor IO) =>
Sem (Embed IO : r) a -> Sem r a
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 (UninterruptipleMask Restoration) r
interpretUninterruptibleMaskFinal