feat: fix monadasyncstate type params

This commit is contained in:
orion 2023-11-22 09:42:01 -06:00
parent 82b8af2a94
commit 02a6aa5ffc
Signed by: orion
GPG Key ID: 6D4165AE4C928719

View File

@ -26,14 +26,23 @@ import Effect.Class (class MonadEffect)
import Effect.Unlift (class MonadUnliftEffect)
-- | Concurrency-safe monads with shared mutable state of type `s`
class MonadAsyncState :: (Type -> Type) -> Type -> (Type -> Type) -> ((Type -> Type) -> Type -> Type) -> Constraint
class (Monad m, MonadTrans t, MonadAsk (w s) (t m)) <= MonadAsyncState w s m t | m -> w, m -> s, t -> m
class MonadAsyncState :: (Type -> Type) -> Type -> (Type -> Type) -> Constraint
class (Monad m, MonadAsk (w s) m) <= MonadAsyncState w s m | m -> w, m -> s
-- | Write a new state
-- |
-- | Blocks until write lock is acquired,
-- | then commits the provided state value (discarding the previous state).
asyncPut :: forall w wl rl s m t e. AsyncState w wl rl => MonadAff (t m) => MonadError e (t m) => MonadAsyncState w s m t => s -> t m Unit
asyncPut
:: forall w wl rl s m t e
. MonadTrans t
=> Monad m
=> AsyncState w wl rl
=> MonadAff (t m)
=> MonadError e (t m)
=> MonadAsyncState w s (t m)
=> s
-> t m Unit
asyncPut = asyncWrite <<< const <<< pure <<< (unit /\ _)
-- | Write a new state
@ -42,7 +51,16 @@ asyncPut = asyncWrite <<< const <<< pure <<< (unit /\ _)
-- | commits the provided state value (discarding the previous state) and returns `Just`.
-- |
-- | Otherwise, returns `Nothing`.
asyncTryPut :: forall w wl rl s m t e. AsyncState w wl rl => MonadAff (t m) => MonadError e (t m) => MonadAsyncState w s m t => s -> t m (Maybe Unit)
asyncTryPut
:: forall w wl rl s m t e
. Monad m
=> MonadTrans t
=> AsyncState w wl rl
=> MonadAff (t m)
=> MonadError e (t m)
=> MonadAsyncState w s (t m)
=> s
-> t m (Maybe Unit)
asyncTryPut = asyncTryWrite <<< const <<< pure <<< (unit /\ _)
-- | Write a new state
@ -60,7 +78,16 @@ asyncTryPut = asyncTryWrite <<< const <<< pure <<< (unit /\ _)
-- | strongly recommended that you ensure all state updates perform structurally immutable
-- | updates rather than in-place mutation so that the object reference is not affected by
-- | valid state updates performed by other concurrent computations.
asyncWrite :: forall w wl rl s m t a e. MonadAff (t m) => AsyncState w wl rl => MonadError e (t m) => MonadAsyncState w s m t => (s -> m (a /\ s)) -> t m a
asyncWrite
:: forall w wl rl s m t a e
. Monad m
=> MonadTrans t
=> MonadAff (t m)
=> AsyncState w wl rl
=> MonadError e (t m)
=> MonadAsyncState w s (t m)
=> (s -> m (a /\ s))
-> t m a
asyncWrite f = do
state <- ask
lock :: wl s <- State.lock state
@ -76,7 +103,16 @@ asyncWrite f = do
-- | and returns `Just`.
-- |
-- | If a lock was not available immediately, does not block and returns `Nothing`
asyncTryWrite :: forall w wl rl s m t a e. MonadError e (t m) => MonadAff (t m) => AsyncState w wl rl => MonadAsyncState w s m t => (s -> m (a /\ s)) -> t m (Maybe a)
asyncTryWrite
:: forall w wl rl s m t a e
. MonadTrans t
=> Monad m
=> MonadError e (t m)
=> MonadAff (t m)
=> AsyncState w wl rl
=> MonadAsyncState w s (t m)
=> (s -> m (a /\ s))
-> t m (Maybe a)
asyncTryWrite f = do
state <- ask
lockM :: Maybe (wl s) <- State.tryLock state
@ -95,7 +131,16 @@ asyncTryWrite f = do
-- | If the state update function succeeds, the new state value will be committed.
-- |
-- | If the state update function throws, the error will be rethrown after releasing the write lock.
asyncModify :: forall w wl rl s m t e. AsyncState w wl rl => MonadAff (t m) => MonadError e (t m) => MonadAsyncState w s m t => (s -> m s) -> t m Unit
asyncModify
:: forall w wl rl s m t e
. MonadTrans t
=> Monad m
=> AsyncState w wl rl
=> MonadAff (t m)
=> MonadError e (t m)
=> MonadAsyncState w s (t m)
=> (s -> m s)
-> t m Unit
asyncModify f = asyncWrite (map (unit /\ _) <<< f)
-- | Write a new state
@ -104,7 +149,16 @@ asyncModify f = asyncWrite (map (unit /\ _) <<< f)
-- | and returns `Just`.
-- |
-- | If a lock was not available immediately, does not block and returns `Nothing`
asyncTryModify :: forall w wl rl s m t e. AsyncState w wl rl => MonadAff (t m) => MonadError e (t m) => MonadAsyncState w s m t => (s -> m s) -> t m (Maybe Unit)
asyncTryModify
:: forall w wl rl s m t e
. Monad m
=> MonadTrans t
=> AsyncState w wl rl
=> MonadAff (t m)
=> MonadError e (t m)
=> MonadAsyncState w s (t m)
=> (s -> m s)
-> t m (Maybe Unit)
asyncTryModify f = asyncTryWrite (map (unit /\ _) <<< f)
-- | Get the current state
@ -116,7 +170,15 @@ asyncTryModify f = asyncTryWrite (map (unit /\ _) <<< f)
-- | strongly recommended that you ensure all state updates perform structurally immutable
-- | updates rather than in-place mutation so that the object reference is not affected by
-- | valid state updates performed by other concurrent computations.
asyncGet :: forall w wl rl s m t e. AsyncState w wl rl => MonadAff (t m) => MonadError e (t m) => MonadAsyncState w s m t => t m s
asyncGet
:: forall w wl rl s m t e
. MonadTrans t
=> Monad m
=> AsyncState w wl rl
=> MonadAff (t m)
=> MonadError e (t m)
=> MonadAsyncState w s (t m)
=> t m s
asyncGet = asyncRead pure
-- | If a read lock may be acquired immediately, acquires it and returns the current
@ -129,7 +191,15 @@ asyncGet = asyncRead pure
-- | strongly recommended that you ensure all state updates perform structurally immutable
-- | updates rather than in-place mutation so that the object reference is not affected by
-- | valid state updates performed by other concurrent computations.
asyncTryGet :: forall w wl rl s m t e. AsyncState w wl rl => MonadAff (t m) => MonadError e (t m) => MonadAsyncState w s m t => t m (Maybe s)
asyncTryGet
:: forall w wl rl s m t e
. Monad m
=> MonadTrans t
=> AsyncState w wl rl
=> MonadAff (t m)
=> MonadError e (t m)
=> MonadAsyncState w s (t m)
=> t m (Maybe s)
asyncTryGet = asyncTryRead pure
-- | Get the current state
@ -141,7 +211,16 @@ asyncTryGet = asyncTryRead pure
-- | strongly recommended that you ensure all state updates perform structurally immutable
-- | updates rather than in-place mutation so that the object reference is not affected by
-- | valid state updates performed by other concurrent computations.
asyncRead :: forall w wl rl s m t a e. AsyncState w wl rl => MonadAff (t m) => MonadError e (t m) => MonadAsyncState w s m t => (s -> m a) -> t m a
asyncRead
:: forall w wl rl s m t a e
. MonadTrans t
=> Monad m
=> AsyncState w wl rl
=> MonadAff (t m)
=> MonadError e (t m)
=> MonadAsyncState w s (t m)
=> (s -> m a)
-> t m a
asyncRead f = do
state <- ask
lock :: rl s <- State.lock state
@ -162,7 +241,16 @@ asyncRead f = do
-- | strongly recommended that you ensure all state updates perform structurally immutable
-- | updates rather than in-place mutation so that the object reference is not affected by
-- | valid state updates performed by other concurrent computations.
asyncTryRead :: forall w wl rl s m t a e. AsyncState w wl rl => MonadAff (t m) => MonadError e (t m) => MonadAsyncState w s m t => (s -> m a) -> t m (Maybe a)
asyncTryRead
:: forall w wl rl s m t a e
. MonadTrans t
=> Monad m
=> MonadAff (t m)
=> MonadError e (t m)
=> AsyncState w wl rl
=> MonadAsyncState w s (t m)
=> (s -> m a)
-> t m (Maybe a)
asyncTryRead f = do
state <- ask
lockM :: Maybe (rl s) <- State.tryLock state
@ -207,7 +295,7 @@ instance (MonadBracket e f m) => MonadBracket e f (AsyncStateT w s m) where
uninterruptible a = wrap $ uninterruptible $ unwrap a
never = wrap never
instance (AsyncState w wl rl, MonadAff m) => MonadAsyncState w s m (AsyncStateT w s)
instance (AsyncState w wl rl, MonadAff m) => MonadAsyncState w s (AsyncStateT w s m)
-- | `AsyncStateT` pinned to use `RwLock`
type RwLockStateT s m = AsyncStateT RwLock s m