polysemy-conc-0.1.0.1: lib/Polysemy/Conc/Queue.hs
-- |Description: Pure Queue interpreters
module Polysemy.Conc.Queue where
import Polysemy.AtomicState (atomicState')
import Polysemy.State (State, evalState, get, gets, put)
import qualified Polysemy.Conc.Data.Queue as Queue
import Polysemy.Conc.Data.Queue (Queue)
import qualified Polysemy.Conc.Data.QueueResult as QueueResult
import Polysemy.Conc.Data.QueueResult (QueueResult)
-- |Reinterpret 'Queue' as 'AtomicState' with a list that cannot be written to.
-- Useful for testing.
interpretQueueListReadOnlyAtomicWith ::
∀ d r .
Member (AtomicState [d]) r =>
InterpreterFor (Queue d) r
interpretQueueListReadOnlyAtomicWith =
interpret \case
Queue.Read ->
read
Queue.TryRead ->
read
Queue.ReadTimeout _ ->
read
Queue.Peek ->
peek
Queue.TryPeek ->
peek
Queue.Write _ ->
pass
Queue.TryWrite _ ->
pure QueueResult.NotAvailable
Queue.WriteTimeout _ _ ->
pure QueueResult.NotAvailable
Queue.Closed ->
atomicGets @[d] null
Queue.Close ->
atomicPut @[d] []
where
read :: Sem r (QueueResult d)
read =
atomicState' @[d] \case
[] -> ([], QueueResult.Closed)
h : t -> (t, QueueResult.Success h)
peek :: Sem r (QueueResult d)
peek =
atomicGets @[d] \case
[] -> QueueResult.Closed
h : _ -> QueueResult.Success h
{-# INLINE interpretQueueListReadOnlyAtomicWith #-}
-- |Variant of 'interpretQueueListReadOnlyAtomicWith' that interprets the 'AtomicState'.
interpretQueueListReadOnlyAtomic ::
∀ d r .
Member (Embed IO) r =>
[d] ->
InterpreterFor (Queue d) r
interpretQueueListReadOnlyAtomic ds sem = do
tv <- newTVarIO ds
runAtomicStateTVar tv (interpretQueueListReadOnlyAtomicWith (raiseUnder sem))
{-# INLINE interpretQueueListReadOnlyAtomic #-}
-- |Reinterpret 'Queue' as 'State' with a list that cannot be written to.
-- Useful for testing.
interpretQueueListReadOnlyStateWith ::
∀ d r .
Member (State [d]) r =>
InterpreterFor (Queue d) r
interpretQueueListReadOnlyStateWith =
interpret \case
Queue.Read ->
read
Queue.TryRead ->
read
Queue.ReadTimeout _ ->
read
Queue.Peek ->
peek
Queue.TryPeek ->
peek
Queue.Write _ ->
pass
Queue.TryWrite _ ->
pure QueueResult.NotAvailable
Queue.WriteTimeout _ _ ->
pure QueueResult.NotAvailable
Queue.Closed ->
gets @[d] null
Queue.Close ->
put @[d] []
where
read :: Sem r (QueueResult d)
read =
get @[d] >>= \case
[] -> pure QueueResult.Closed
h : t -> QueueResult.Success h <$ put t
peek :: Sem r (QueueResult d)
peek =
gets @[d] \case
[] -> QueueResult.Closed
h : _ -> QueueResult.Success h
{-# INLINE interpretQueueListReadOnlyStateWith #-}
-- |Variant of 'interpretQueueListReadOnlyAtomicWith' that interprets the 'State'.
interpretQueueListReadOnlyState ::
∀ d r .
Member (Embed IO) r =>
[d] ->
InterpreterFor (Queue d) r
interpretQueueListReadOnlyState ds sem = do
evalState ds (interpretQueueListReadOnlyStateWith (raiseUnder sem))
{-# INLINE interpretQueueListReadOnlyState #-}