packages feed

effectful-core 2.3.1.0 → 2.4.0.0

raw patch · 29 files changed

+1749/−633 lines, 29 filesdep +deepseqdep +safe-exceptionsdep +strict-mutable-basedep ~primitivePVP ok

version bump matches the API change (PVP)

Dependencies added: deepseq, safe-exceptions, strict-mutable-base

Dependency ranges changed: primitive

API changes (from Hackage documentation)

- Effectful.Error.Dynamic: [ThrowError] :: e -> Error e m a
- Effectful.Internal.Effect: instance (Effectful.Internal.Effect.KnownPrefix es, Effectful.Internal.Effect.IsUnknownSuffixOf xs es) => Effectful.Internal.Effect.Subset xs es
- Effectful.Internal.Effect: instance (e Effectful.Internal.Effect.:> es, Effectful.Internal.Effect.Subset xs es) => Effectful.Internal.Effect.Subset (e : xs) es
- Effectful.Internal.Effect: instance (xs GHC.Types.~ es) => Effectful.Internal.Effect.IsUnknownSuffixOf xs es
- Effectful.Internal.Effect: instance Effectful.Internal.Effect.IsUnknownSuffixOf xs es => Effectful.Internal.Effect.IsUnknownSuffixOf xs (e : es)
- Effectful.Internal.Monad: consEnv :: EffectRep (DispatchOf e) e -> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env (e : es))
- Effectful.Internal.Monad: getEnv :: forall e es. e :> es => Env es -> IO (EffectRep (DispatchOf e) e)
- Effectful.Internal.Monad: modifyEnv :: forall e es. e :> es => Env es -> (EffectRep (DispatchOf e) e -> IO (EffectRep (DispatchOf e) e)) -> IO ()
- Effectful.Internal.Monad: putEnv :: forall e es. e :> es => Env es -> EffectRep (DispatchOf e) e -> IO ()
- Effectful.Internal.Monad: stateEnv :: forall e es a. e :> es => Env es -> (EffectRep (DispatchOf e) e -> IO (a, EffectRep (DispatchOf e) e)) -> IO a
- Effectful.Internal.Unlift: concUnlift :: HasCallStack => Persistence -> Limit -> ((forall r. m r -> IO r) -> IO a) -> Env es -> (forall r. m r -> Env es -> IO r) -> IO a
- Effectful.Internal.Unlift: seqUnlift :: HasCallStack => ((forall r. m r -> IO r) -> IO a) -> Env es -> (forall r. m r -> Env es -> IO r) -> IO a
- Effectful.Internal.Utils: data IORef' a
- Effectful.Internal.Utils: data MVar' a
- Effectful.Internal.Utils: instance GHC.Classes.Eq (Effectful.Internal.Utils.IORef' a)
- Effectful.Internal.Utils: instance GHC.Classes.Eq (Effectful.Internal.Utils.MVar' a)
- Effectful.Internal.Utils: modifyMVar' :: MVar' a -> (a -> IO (a, r)) -> IO r
- Effectful.Internal.Utils: modifyMVar_' :: MVar' a -> (a -> IO a) -> IO ()
- Effectful.Internal.Utils: newIORef' :: a -> IO (IORef' a)
- Effectful.Internal.Utils: newMVar' :: a -> IO (MVar' a)
- Effectful.Internal.Utils: readIORef' :: IORef' a -> IO a
- Effectful.Internal.Utils: readMVar' :: MVar' a -> IO a
- Effectful.Internal.Utils: toMVar' :: MVar a -> IO (MVar' a)
- Effectful.Internal.Utils: writeIORef' :: IORef' a -> a -> IO ()
- Effectful.Labeled: data Labeled (label :: k) (e :: Effect) :: Effect
+ Effectful: SeqForkUnlift :: UnliftStrategy
+ Effectful.Dispatch.Dynamic: class Subset subEs es => KnownSubset (subEs :: [Effect]) (es :: [Effect])
+ Effectful.Dispatch.Dynamic: imposeWith :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => (Eff handlerEs a -> Eff es b) -> Eff es a -> EffectHandler e handlerEs -> Eff es b
+ Effectful.Dispatch.Dynamic: imposeWith_ :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => (Eff handlerEs a -> Eff es b) -> Eff es a -> EffectHandler_ e handlerEs -> Eff es b
+ Effectful.Dispatch.Dynamic: impose_ :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => (Eff handlerEs a -> Eff es b) -> EffectHandler_ e handlerEs -> Eff es a -> Eff es b
+ Effectful.Dispatch.Dynamic: interposeWith :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => Eff es a -> EffectHandler e es -> Eff es a
+ Effectful.Dispatch.Dynamic: interposeWith_ :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => Eff es a -> EffectHandler_ e es -> Eff es a
+ Effectful.Dispatch.Dynamic: interpose_ :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => EffectHandler_ e es -> Eff es a -> Eff es a
+ Effectful.Dispatch.Dynamic: interpretWith :: (HasCallStack, DispatchOf e ~ Dynamic) => Eff (e : es) a -> EffectHandler e es -> Eff es a
+ Effectful.Dispatch.Dynamic: interpretWith_ :: (HasCallStack, DispatchOf e ~ Dynamic) => Eff (e : es) a -> EffectHandler_ e es -> Eff es a
+ Effectful.Dispatch.Dynamic: interpret_ :: (HasCallStack, DispatchOf e ~ Dynamic) => EffectHandler_ e es -> Eff (e : es) a -> Eff es a
+ Effectful.Dispatch.Dynamic: reinterpretWith :: (HasCallStack, DispatchOf e ~ Dynamic) => (Eff handlerEs a -> Eff es b) -> Eff (e : es) a -> EffectHandler e handlerEs -> Eff es b
+ Effectful.Dispatch.Dynamic: reinterpretWith_ :: (HasCallStack, DispatchOf e ~ Dynamic) => (Eff handlerEs a -> Eff es b) -> Eff (e : es) a -> EffectHandler_ e handlerEs -> Eff es b
+ Effectful.Dispatch.Dynamic: reinterpret_ :: (HasCallStack, DispatchOf e ~ Dynamic) => (Eff handlerEs a -> Eff es b) -> EffectHandler_ e handlerEs -> Eff (e : es) a -> Eff es b
+ Effectful.Error.Dynamic: [ThrowErrorWith] :: (e -> String) -> e -> Error e m a
+ Effectful.Error.Dynamic: throwErrorWith :: (HasCallStack, Error e :> es) => (e -> String) -> e -> Eff es a
+ Effectful.Error.Dynamic: throwError_ :: (HasCallStack, Error e :> es) => e -> Eff es a
+ Effectful.Error.Static: throwErrorWith :: forall e es a. (HasCallStack, Error e :> es) => (e -> String) -> e -> Eff es a
+ Effectful.Error.Static: throwError_ :: forall e es a. (HasCallStack, Error e :> es) => e -> Eff es a
+ Effectful.Exception: AllocationLimitExceeded :: AllocationLimitExceeded
+ Effectful.Exception: AssertionFailed :: String -> AssertionFailed
+ Effectful.Exception: AsyncExceptionWrapper :: e -> AsyncExceptionWrapper
+ Effectful.Exception: BlockedIndefinitelyOnMVar :: BlockedIndefinitelyOnMVar
+ Effectful.Exception: BlockedIndefinitelyOnSTM :: BlockedIndefinitelyOnSTM
+ Effectful.Exception: CompactionFailed :: String -> CompactionFailed
+ Effectful.Exception: Deadlock :: Deadlock
+ Effectful.Exception: Denormal :: ArithException
+ Effectful.Exception: DivideByZero :: ArithException
+ Effectful.Exception: ErrorCallWithLocation :: String -> String -> ErrorCall
+ Effectful.Exception: ExitCaseAbort :: ExitCase a
+ Effectful.Exception: ExitCaseException :: SomeException -> ExitCase a
+ Effectful.Exception: ExitCaseSuccess :: a -> ExitCase a
+ Effectful.Exception: Handler :: (e -> m a) -> Handler (m :: Type -> Type) a
+ Effectful.Exception: HeapOverflow :: AsyncException
+ Effectful.Exception: IndexOutOfBounds :: String -> ArrayException
+ Effectful.Exception: LossOfPrecision :: ArithException
+ Effectful.Exception: NestedAtomically :: NestedAtomically
+ Effectful.Exception: NoMethodError :: String -> NoMethodError
+ Effectful.Exception: NonTermination :: NonTermination
+ Effectful.Exception: Overflow :: ArithException
+ Effectful.Exception: PatternMatchFail :: String -> PatternMatchFail
+ Effectful.Exception: RatioZeroDenominator :: ArithException
+ Effectful.Exception: RecConError :: String -> RecConError
+ Effectful.Exception: RecSelError :: String -> RecSelError
+ Effectful.Exception: RecUpdError :: String -> RecUpdError
+ Effectful.Exception: SomeAsyncException :: e -> SomeAsyncException
+ Effectful.Exception: SomeException :: e -> SomeException
+ Effectful.Exception: StackOverflow :: AsyncException
+ Effectful.Exception: StringException :: String -> CallStack -> StringException
+ Effectful.Exception: SyncExceptionWrapper :: e -> SyncExceptionWrapper
+ Effectful.Exception: ThreadKilled :: AsyncException
+ Effectful.Exception: TypeError :: String -> TypeError
+ Effectful.Exception: UndefinedElement :: String -> ArrayException
+ Effectful.Exception: Underflow :: ArithException
+ Effectful.Exception: UserInterrupt :: AsyncException
+ Effectful.Exception: assert :: Bool -> a -> a
+ Effectful.Exception: asyncExceptionFromException :: Exception e => SomeException -> Maybe e
+ Effectful.Exception: asyncExceptionToException :: Exception e => e -> SomeException
+ Effectful.Exception: bracket :: (HasCallStack, MonadMask m) => m a -> (a -> m b) -> (a -> m c) -> m c
+ Effectful.Exception: bracketOnError :: (HasCallStack, MonadMask m) => m a -> (a -> m b) -> (a -> m c) -> m c
+ Effectful.Exception: bracketOnError_ :: (HasCallStack, MonadMask m) => m a -> m b -> m c -> m c
+ Effectful.Exception: bracketWithError :: (HasCallStack, MonadMask m) => m a -> (Maybe SomeException -> a -> m b) -> (a -> m c) -> m c
+ Effectful.Exception: bracket_ :: (HasCallStack, MonadMask m) => m a -> m b -> m c -> m c
+ Effectful.Exception: catch :: (MonadCatch m, HasCallStack, Exception e) => m a -> (e -> m a) -> m a
+ Effectful.Exception: catchAny :: (HasCallStack, MonadCatch m) => m a -> (SomeException -> m a) -> m a
+ Effectful.Exception: catchAnyDeep :: (HasCallStack, MonadCatch m, MonadIO m, NFData a) => m a -> (SomeException -> m a) -> m a
+ Effectful.Exception: catchAsync :: (HasCallStack, MonadCatch m, Exception e) => m a -> (e -> m a) -> m a
+ Effectful.Exception: catchDeep :: (HasCallStack, MonadCatch m, MonadIO m, Exception e, NFData a) => m a -> (e -> m a) -> m a
+ Effectful.Exception: catchIO :: (HasCallStack, MonadCatch m) => m a -> (IOException -> m a) -> m a
+ Effectful.Exception: catchIOError :: (HasCallStack, MonadCatch m) => m a -> (IOError -> m a) -> m a
+ Effectful.Exception: catchJust :: (HasCallStack, MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a
+ Effectful.Exception: catches :: (HasCallStack, MonadCatch m, MonadThrow m) => m a -> [Handler m a] -> m a
+ Effectful.Exception: catchesAsync :: (HasCallStack, MonadCatch m, MonadThrow m) => m a -> [Handler m a] -> m a
+ Effectful.Exception: catchesDeep :: (HasCallStack, MonadCatch m, MonadThrow m, MonadIO m, NFData a) => m a -> [Handler m a] -> m a
+ Effectful.Exception: class (Typeable e, Show e) => Exception e
+ Effectful.Exception: class MonadThrow m => MonadCatch (m :: Type -> Type)
+ Effectful.Exception: class MonadCatch m => MonadMask (m :: Type -> Type)
+ Effectful.Exception: class Monad m => MonadThrow (m :: Type -> Type)
+ Effectful.Exception: data () => AllocationLimitExceeded
+ Effectful.Exception: data () => ArithException
+ Effectful.Exception: data () => ArrayException
+ Effectful.Exception: data () => AsyncException
+ Effectful.Exception: data () => AsyncExceptionWrapper
+ Effectful.Exception: data () => BlockedIndefinitelyOnMVar
+ Effectful.Exception: data () => BlockedIndefinitelyOnSTM
+ Effectful.Exception: data () => Deadlock
+ Effectful.Exception: data () => ErrorCall
+ Effectful.Exception: data () => ExitCase a
+ Effectful.Exception: data () => Handler (m :: Type -> Type) a
+ Effectful.Exception: data () => IOException
+ Effectful.Exception: data () => NestedAtomically
+ Effectful.Exception: data () => NonTermination
+ Effectful.Exception: data () => SomeAsyncException
+ Effectful.Exception: data () => SomeException
+ Effectful.Exception: data () => StringException
+ Effectful.Exception: data () => SyncExceptionWrapper
+ Effectful.Exception: displayException :: Exception e => e -> String
+ Effectful.Exception: evaluate :: a -> Eff es a
+ Effectful.Exception: evaluateDeep :: NFData a => a -> Eff es a
+ Effectful.Exception: finally :: (HasCallStack, MonadMask m) => m a -> m b -> m a
+ Effectful.Exception: fromException :: Exception e => SomeException -> Maybe e
+ Effectful.Exception: generalBracket :: (MonadMask m, HasCallStack) => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
+ Effectful.Exception: handle :: (HasCallStack, MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
+ Effectful.Exception: handleAny :: (HasCallStack, MonadCatch m) => (SomeException -> m a) -> m a -> m a
+ Effectful.Exception: handleAnyDeep :: (HasCallStack, MonadCatch m, MonadIO m, NFData a) => (SomeException -> m a) -> m a -> m a
+ Effectful.Exception: handleAsync :: (HasCallStack, MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
+ Effectful.Exception: handleDeep :: (HasCallStack, MonadCatch m, Exception e, MonadIO m, NFData a) => (e -> m a) -> m a -> m a
+ Effectful.Exception: handleIO :: (HasCallStack, MonadCatch m) => (IOException -> m a) -> m a -> m a
+ Effectful.Exception: handleIOError :: (HasCallStack, MonadCatch m) => (IOError -> m a) -> m a -> m a
+ Effectful.Exception: handleJust :: (HasCallStack, MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
+ Effectful.Exception: isAsyncException :: Exception e => e -> Bool
+ Effectful.Exception: isSyncException :: Exception e => e -> Bool
+ Effectful.Exception: mask :: (MonadMask m, HasCallStack) => ((forall a. () => m a -> m a) -> m b) -> m b
+ Effectful.Exception: newtype () => AssertionFailed
+ Effectful.Exception: newtype () => CompactionFailed
+ Effectful.Exception: newtype () => NoMethodError
+ Effectful.Exception: newtype () => PatternMatchFail
+ Effectful.Exception: newtype () => RecConError
+ Effectful.Exception: newtype () => RecSelError
+ Effectful.Exception: newtype () => RecUpdError
+ Effectful.Exception: newtype () => TypeError
+ Effectful.Exception: onException :: (HasCallStack, MonadMask m) => m a -> m b -> m a
+ Effectful.Exception: pattern ErrorCall :: String -> ErrorCall
+ Effectful.Exception: throwM :: (MonadThrow m, HasCallStack, Exception e) => e -> m a
+ Effectful.Exception: throwString :: (MonadThrow m, HasCallStack) => String -> m a
+ Effectful.Exception: toAsyncException :: Exception e => e -> SomeException
+ Effectful.Exception: toException :: Exception e => e -> SomeException
+ Effectful.Exception: toSyncException :: Exception e => e -> SomeException
+ Effectful.Exception: try :: (HasCallStack, MonadCatch m, Exception e) => m a -> m (Either e a)
+ Effectful.Exception: tryAny :: (HasCallStack, MonadCatch m) => m a -> m (Either SomeException a)
+ Effectful.Exception: tryAnyDeep :: (HasCallStack, MonadCatch m, MonadIO m, NFData a) => m a -> m (Either SomeException a)
+ Effectful.Exception: tryAsync :: (HasCallStack, MonadCatch m, Exception e) => m a -> m (Either e a)
+ Effectful.Exception: tryDeep :: (HasCallStack, MonadCatch m, MonadIO m, Exception e, NFData a) => m a -> m (Either e a)
+ Effectful.Exception: tryIO :: (HasCallStack, MonadCatch m) => m a -> m (Either IOException a)
+ Effectful.Exception: tryJust :: (HasCallStack, MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)
+ Effectful.Exception: uninterruptibleMask :: (MonadMask m, HasCallStack) => ((forall a. () => m a -> m a) -> m b) -> m b
+ Effectful.Exception: withException :: (HasCallStack, MonadMask m, Exception e) => m a -> (e -> m b) -> m a
+ Effectful.Internal.Effect: class Subset subEs es => KnownSubset (subEs :: [Effect]) (es :: [Effect])
+ Effectful.Internal.Effect: instance (Effectful.Internal.Effect.KnownPrefix es, Effectful.Internal.Effect.IsUnknownSuffixOf subEs es) => Effectful.Internal.Effect.Subset subEs es
+ Effectful.Internal.Effect: instance (e Effectful.Internal.Effect.:> es, Effectful.Internal.Effect.KnownSubset subEs es) => Effectful.Internal.Effect.KnownSubset (e : subEs) es
+ Effectful.Internal.Effect: instance (e Effectful.Internal.Effect.:> es, Effectful.Internal.Effect.Subset subEs es) => Effectful.Internal.Effect.Subset (e : subEs) es
+ Effectful.Internal.Effect: instance (subEs GHC.Types.~ es) => Effectful.Internal.Effect.IsUnknownSuffixOf subEs es
+ Effectful.Internal.Effect: instance Effectful.Internal.Effect.IsUnknownSuffixOf subEs es => Effectful.Internal.Effect.IsUnknownSuffixOf subEs (e : es)
+ Effectful.Internal.Effect: instance Effectful.Internal.Effect.KnownSubset '[] es
+ Effectful.Internal.Env: Ref :: !Int -> !Version -> Ref
+ Effectful.Internal.Env: data AnyEffect
+ Effectful.Internal.Env: data AnyRelinker
+ Effectful.Internal.Env: data Ref
+ Effectful.Internal.Env: data Version
+ Effectful.Internal.Env: fromAnyEffect :: AnyEffect -> EffectRep (DispatchOf e) e
+ Effectful.Internal.Env: fromAnyRelinker :: AnyRelinker -> Relinker (EffectRep (DispatchOf e)) e
+ Effectful.Internal.Env: instance Data.Primitive.Types.Prim Effectful.Internal.Env.Ref
+ Effectful.Internal.Env: instance Data.Primitive.Types.Prim Effectful.Internal.Env.Version
+ Effectful.Internal.Env: instance GHC.Classes.Eq Effectful.Internal.Env.Version
+ Effectful.Internal.Env: instance GHC.Classes.Ord Effectful.Internal.Env.Version
+ Effectful.Internal.Env: instance GHC.Show.Show Effectful.Internal.Env.Version
+ Effectful.Internal.Env: toAnyEffect :: EffectRep (DispatchOf e) e -> AnyEffect
+ Effectful.Internal.Env: toAnyRelinker :: Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker
+ Effectful.Internal.Monad: SeqForkUnlift :: UnliftStrategy
+ Effectful.Internal.Monad: seqForkUnliftIO :: HasCallStack => Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
+ Effectful.Internal.Unlift: SeqForkUnlift :: UnliftStrategy
+ Effectful.Internal.Unlift: ephemeralConcUnlift :: (HasCallStack, forall r. Coercible (m r) (Env es -> IO r)) => Env es -> Int -> ((forall r. m r -> IO r) -> IO a) -> IO a
+ Effectful.Internal.Unlift: persistentConcUnlift :: (HasCallStack, forall r. Coercible (m r) (Env es -> IO r)) => Env es -> Bool -> Int -> ((forall r. m r -> IO r) -> IO a) -> IO a
+ Effectful.Labeled: [Labeled] :: forall label e m a. e m a -> Labeled label e m a
+ Effectful.Labeled: newtype Labeled (label :: k) (e :: Effect) :: Effect
+ Effectful.Labeled.Error: [CatchError] :: m a -> (CallStack -> e -> m a) -> Error e m a
+ Effectful.Labeled.Error: [ThrowErrorWith] :: (e -> String) -> e -> Error e m a
+ Effectful.Labeled.Error: catchError :: forall label e es a. (HasCallStack, Labeled label (Error e) :> es) => Eff es a -> (CallStack -> e -> Eff es a) -> Eff es a
+ Effectful.Labeled.Error: data () => CallStack
+ Effectful.Labeled.Error: data Error e :: Effect
+ Effectful.Labeled.Error: getCallStack :: CallStack -> [([Char], SrcLoc)]
+ Effectful.Labeled.Error: handleError :: forall label e es a. (HasCallStack, Labeled label (Error e) :> es) => (CallStack -> e -> Eff es a) -> Eff es a -> Eff es a
+ Effectful.Labeled.Error: prettyCallStack :: CallStack -> String
+ Effectful.Labeled.Error: runError :: forall label e es a. HasCallStack => Eff (Labeled label (Error e) : es) a -> Eff es (Either (CallStack, e) a)
+ Effectful.Labeled.Error: runErrorNoCallStack :: forall label e es a. HasCallStack => Eff (Labeled label (Error e) : es) a -> Eff es (Either e a)
+ Effectful.Labeled.Error: runErrorNoCallStackWith :: forall label e es a. HasCallStack => (e -> Eff es a) -> Eff (Labeled label (Error e) : es) a -> Eff es a
+ Effectful.Labeled.Error: runErrorWith :: forall label e es a. HasCallStack => (CallStack -> e -> Eff es a) -> Eff (Labeled label (Error e) : es) a -> Eff es a
+ Effectful.Labeled.Error: throwError :: forall label e es a. (HasCallStack, Labeled label (Error e) :> es, Show e) => e -> Eff es a
+ Effectful.Labeled.Error: throwErrorWith :: forall label e es a. (HasCallStack, Labeled label (Error e) :> es) => (e -> String) -> e -> Eff es a
+ Effectful.Labeled.Error: throwError_ :: forall label e es a. (HasCallStack, Labeled label (Error e) :> es) => e -> Eff es a
+ Effectful.Labeled.Error: tryError :: forall label e es a. (HasCallStack, Labeled label (Error e) :> es) => Eff es a -> Eff es (Either (CallStack, e) a)
+ Effectful.Labeled.Error: type HasCallStack = ?callStack :: CallStack
+ Effectful.Labeled.Reader: [Ask] :: Reader r m r
+ Effectful.Labeled.Reader: [Local] :: (r -> r) -> m a -> Reader r m a
+ Effectful.Labeled.Reader: ask :: forall label r es. (HasCallStack, Labeled label (Reader r) :> es) => Eff es r
+ Effectful.Labeled.Reader: asks :: forall label r es a. (HasCallStack, Labeled label (Reader r) :> es) => (r -> a) -> Eff es a
+ Effectful.Labeled.Reader: data Reader r :: Effect
+ Effectful.Labeled.Reader: local :: forall label r es a. (HasCallStack, Labeled label (Reader r) :> es) => (r -> r) -> Eff es a -> Eff es a
+ Effectful.Labeled.Reader: runReader :: forall label r es a. HasCallStack => r -> Eff (Labeled label (Reader r) : es) a -> Eff es a
+ Effectful.Labeled.State: [Get] :: State s m s
+ Effectful.Labeled.State: [Put] :: s -> State s m ()
+ Effectful.Labeled.State: [StateM] :: (s -> m (a, s)) -> State s m a
+ Effectful.Labeled.State: [State] :: (s -> (a, s)) -> State s m a
+ Effectful.Labeled.State: data State s :: Effect
+ Effectful.Labeled.State: evalStateLocal :: forall label s es a. HasCallStack => s -> Eff (Labeled label (State s) : es) a -> Eff es a
+ Effectful.Labeled.State: evalStateShared :: forall label s es a. HasCallStack => s -> Eff (Labeled label (State s) : es) a -> Eff es a
+ Effectful.Labeled.State: execStateLocal :: forall label s es a. HasCallStack => s -> Eff (Labeled label (State s) : es) a -> Eff es s
+ Effectful.Labeled.State: execStateShared :: forall label s es a. HasCallStack => s -> Eff (Labeled label (State s) : es) a -> Eff es s
+ Effectful.Labeled.State: get :: forall label s es. (HasCallStack, Labeled label (State s) :> es) => Eff es s
+ Effectful.Labeled.State: gets :: forall label s es a. (HasCallStack, Labeled label (State s) :> es) => (s -> a) -> Eff es a
+ Effectful.Labeled.State: modify :: forall label s es. (HasCallStack, Labeled label (State s) :> es) => (s -> s) -> Eff es ()
+ Effectful.Labeled.State: modifyM :: forall label s es. (HasCallStack, Labeled label (State s) :> es) => (s -> Eff es s) -> Eff es ()
+ Effectful.Labeled.State: put :: forall label s es. (HasCallStack, Labeled label (State s) :> es) => s -> Eff es ()
+ Effectful.Labeled.State: runStateLocal :: forall label s es a. HasCallStack => s -> Eff (Labeled label (State s) : es) a -> Eff es (a, s)
+ Effectful.Labeled.State: runStateShared :: forall label s es a. HasCallStack => s -> Eff (Labeled label (State s) : es) a -> Eff es (a, s)
+ Effectful.Labeled.State: state :: forall label s es a. (HasCallStack, Labeled label (State s) :> es) => (s -> (a, s)) -> Eff es a
+ Effectful.Labeled.State: stateM :: forall label s es a. (HasCallStack, Labeled label (State s) :> es) => (s -> Eff es (a, s)) -> Eff es a
+ Effectful.Labeled.Writer: [Listen] :: m a -> Writer w m (a, w)
+ Effectful.Labeled.Writer: [Tell] :: w -> Writer w m ()
+ Effectful.Labeled.Writer: data Writer w :: Effect
+ Effectful.Labeled.Writer: execWriterLocal :: forall label w es a. (HasCallStack, Monoid w) => Eff (Labeled label (Writer w) : es) a -> Eff es w
+ Effectful.Labeled.Writer: execWriterShared :: forall label w es a. (HasCallStack, Monoid w) => Eff (Labeled label (Writer w) : es) a -> Eff es w
+ Effectful.Labeled.Writer: listen :: forall label w es a. (HasCallStack, Labeled label (Writer w) :> es) => Eff es a -> Eff es (a, w)
+ Effectful.Labeled.Writer: listens :: forall label w es a b. (HasCallStack, Labeled label (Writer w) :> es) => (w -> b) -> Eff es a -> Eff es (a, b)
+ Effectful.Labeled.Writer: runWriterLocal :: forall label w es a. (HasCallStack, Monoid w) => Eff (Labeled label (Writer w) : es) a -> Eff es (a, w)
+ Effectful.Labeled.Writer: runWriterShared :: forall label w es a. (HasCallStack, Monoid w) => Eff (Labeled label (Writer w) : es) a -> Eff es (a, w)
+ Effectful.Labeled.Writer: tell :: forall label w es. (HasCallStack, Labeled label (Writer w) :> es) => w -> Eff es ()
+ Effectful.NonDet: instance GHC.Show.Show Effectful.NonDet.ErrorEmpty
- Effectful: class KnownPrefix es => Subset (xs :: [Effect]) (es :: [Effect])
+ Effectful: class KnownPrefix es => Subset (subEs :: [Effect]) (es :: [Effect])
- Effectful: inject :: Subset xs es => Eff xs a -> Eff es a
+ Effectful: inject :: Subset subEs es => Eff subEs a -> Eff es a
- Effectful: runEff :: Eff '[IOE] a -> IO a
+ Effectful: runEff :: HasCallStack => Eff '[IOE] a -> IO a
- Effectful: runPureEff :: Eff '[] a -> a
+ Effectful: runPureEff :: HasCallStack => Eff '[] a -> a
- Effectful.Dispatch.Dynamic: impose :: forall e es handlerEs a b. (DispatchOf e ~ Dynamic, e :> es) => (Eff handlerEs a -> Eff es b) -> EffectHandler e handlerEs -> Eff es a -> Eff es b
+ Effectful.Dispatch.Dynamic: impose :: forall e es handlerEs a b. (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => (Eff handlerEs a -> Eff es b) -> EffectHandler e handlerEs -> Eff es a -> Eff es b
- Effectful.Dispatch.Dynamic: interpose :: forall e es a. (DispatchOf e ~ Dynamic, e :> es) => EffectHandler e es -> Eff es a -> Eff es a
+ Effectful.Dispatch.Dynamic: interpose :: forall e es a. (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => EffectHandler e es -> Eff es a -> Eff es a
- Effectful.Dispatch.Dynamic: interpret :: DispatchOf e ~ Dynamic => EffectHandler e es -> Eff (e : es) a -> Eff es a
+ Effectful.Dispatch.Dynamic: interpret :: (HasCallStack, DispatchOf e ~ Dynamic) => EffectHandler e es -> Eff (e : es) a -> Eff es a
- Effectful.Dispatch.Dynamic: localBorrow :: (e :> localEs, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> UnliftStrategy -> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a) -> Eff es a
+ Effectful.Dispatch.Dynamic: localBorrow :: forall borrowedEs es handlerEs localEs a. (HasCallStack, KnownSubset borrowedEs localEs, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> UnliftStrategy -> ((forall r. Eff (borrowedEs ++ es) r -> Eff es r) -> Eff es a) -> Eff es a
- Effectful.Dispatch.Dynamic: localLend :: (e :> es, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> UnliftStrategy -> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a) -> Eff es a
+ Effectful.Dispatch.Dynamic: localLend :: forall lentEs es handlerEs localEs a. (HasCallStack, KnownSubset lentEs es, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> UnliftStrategy -> ((forall r. Eff (lentEs ++ localEs) r -> Eff localEs r) -> Eff es a) -> Eff es a
- Effectful.Dispatch.Dynamic: localSeqBorrow :: (e :> localEs, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a) -> Eff es a
+ Effectful.Dispatch.Dynamic: localSeqBorrow :: forall borrowedEs es handlerEs localEs a. (HasCallStack, KnownSubset borrowedEs localEs, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> ((forall r. Eff (borrowedEs ++ es) r -> Eff es r) -> Eff es a) -> Eff es a
- Effectful.Dispatch.Dynamic: localSeqLend :: (e :> es, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a) -> Eff es a
+ Effectful.Dispatch.Dynamic: localSeqLend :: forall lentEs es handlerEs localEs a. (HasCallStack, KnownSubset lentEs es, SharedSuffix es handlerEs) => LocalEnv localEs handlerEs -> ((forall r. Eff (lentEs ++ localEs) r -> Eff localEs r) -> Eff es a) -> Eff es a
- Effectful.Dispatch.Dynamic: reinterpret :: DispatchOf e ~ Dynamic => (Eff handlerEs a -> Eff es b) -> EffectHandler e handlerEs -> Eff (e : es) a -> Eff es b
+ Effectful.Dispatch.Dynamic: reinterpret :: (HasCallStack, DispatchOf e ~ Dynamic) => (Eff handlerEs a -> Eff es b) -> EffectHandler e handlerEs -> Eff (e : es) a -> Eff es b
- Effectful.Dispatch.Dynamic: type EffectHandler e es = forall a localEs. (HasCallStack, e :> localEs) => -- | Capture of the local environment for handling local 'Eff' computations -- when @e@ is a higher order effect. LocalEnv localEs es -> -- | The effect performed in the local environment. e (Eff localEs) a -> Eff es a
+ Effectful.Dispatch.Dynamic: type EffectHandler_ (e :: Effect) (es :: [Effect]) = forall a localEs. HasCallStack => -- | The operation. e (Eff localEs) a -> Eff es a
- Effectful.Dispatch.Static: evalStaticRep :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es a
+ Effectful.Dispatch.Static: evalStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es a
- Effectful.Dispatch.Static: execStaticRep :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (StaticRep e)
+ Effectful.Dispatch.Static: execStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (StaticRep e)
- Effectful.Dispatch.Static: getStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => Eff es (StaticRep e)
+ Effectful.Dispatch.Static: getStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => Eff es (StaticRep e)
- Effectful.Dispatch.Static: localStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
+ Effectful.Dispatch.Static: localStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
- Effectful.Dispatch.Static: putStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => StaticRep e -> Eff es ()
+ Effectful.Dispatch.Static: putStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => StaticRep e -> Eff es ()
- Effectful.Dispatch.Static: runStaticRep :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (a, StaticRep e)
+ Effectful.Dispatch.Static: runStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (a, StaticRep e)
- Effectful.Dispatch.Static: stateStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> (a, StaticRep e)) -> Eff es a
+ Effectful.Dispatch.Static: stateStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> (a, StaticRep e)) -> Eff es a
- Effectful.Dispatch.Static: stateStaticRepM :: (DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> Eff es (a, StaticRep e)) -> Eff es a
+ Effectful.Dispatch.Static: stateStaticRepM :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> Eff es (a, StaticRep e)) -> Eff es a
- Effectful.Dispatch.Static.Primitive: [Relinker] :: ((forall es. Env es -> IO (Env es)) -> rep e -> IO (rep e)) -> Relinker rep e
+ Effectful.Dispatch.Static.Primitive: [Relinker] :: (HasCallStack => (forall es. Env es -> IO (Env es)) -> rep e -> IO (rep e)) -> Relinker rep e
- Effectful.Dispatch.Static.Primitive: cloneEnv :: Env es -> IO (Env es)
+ Effectful.Dispatch.Static.Primitive: cloneEnv :: HasCallStack => Env es -> IO (Env es)
- Effectful.Dispatch.Static.Primitive: consEnv :: EffectRep (DispatchOf e) e -> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env (e : es))
+ Effectful.Dispatch.Static.Primitive: consEnv :: HasCallStack => EffectRep (DispatchOf e) e -> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env (e : es))
- Effectful.Dispatch.Static.Primitive: emptyEnv :: IO (Env '[])
+ Effectful.Dispatch.Static.Primitive: emptyEnv :: HasCallStack => IO (Env '[])
- Effectful.Dispatch.Static.Primitive: getEnv :: forall e es. e :> es => Env es -> IO (EffectRep (DispatchOf e) e)
+ Effectful.Dispatch.Static.Primitive: getEnv :: forall e es. (HasCallStack, e :> es) => Env es -> IO (EffectRep (DispatchOf e) e)
- Effectful.Dispatch.Static.Primitive: modifyEnv :: forall e es. e :> es => Env es -> (EffectRep (DispatchOf e) e -> IO (EffectRep (DispatchOf e) e)) -> IO ()
+ Effectful.Dispatch.Static.Primitive: modifyEnv :: forall e es. (HasCallStack, e :> es) => Env es -> (EffectRep (DispatchOf e) e -> EffectRep (DispatchOf e) e) -> IO ()
- Effectful.Dispatch.Static.Primitive: putEnv :: forall e es. e :> es => Env es -> EffectRep (DispatchOf e) e -> IO ()
+ Effectful.Dispatch.Static.Primitive: putEnv :: forall e es. (HasCallStack, e :> es) => Env es -> EffectRep (DispatchOf e) e -> IO ()
- Effectful.Dispatch.Static.Primitive: restoreEnv :: Env es -> Env es -> IO ()
+ Effectful.Dispatch.Static.Primitive: restoreEnv :: HasCallStack => Env es -> Env es -> IO ()
- Effectful.Dispatch.Static.Primitive: stateEnv :: forall e es a. e :> es => Env es -> (EffectRep (DispatchOf e) e -> IO (a, EffectRep (DispatchOf e) e)) -> IO a
+ Effectful.Dispatch.Static.Primitive: stateEnv :: forall e es a. (HasCallStack, e :> es) => Env es -> (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e)) -> IO a
- Effectful.Dispatch.Static.Primitive: unconsEnv :: Env (e : es) -> IO ()
+ Effectful.Dispatch.Static.Primitive: unconsEnv :: HasCallStack => Env (e : es) -> IO ()
- Effectful.Error.Dynamic: handleError :: Error e :> es => (CallStack -> e -> Eff es a) -> Eff es a -> Eff es a
+ Effectful.Error.Dynamic: handleError :: (HasCallStack, Error e :> es) => (CallStack -> e -> Eff es a) -> Eff es a -> Eff es a
- Effectful.Error.Dynamic: runError :: Eff (Error e : es) a -> Eff es (Either (CallStack, e) a)
+ Effectful.Error.Dynamic: runError :: HasCallStack => Eff (Error e : es) a -> Eff es (Either (CallStack, e) a)
- Effectful.Error.Dynamic: runErrorNoCallStack :: Eff (Error e : es) a -> Eff es (Either e a)
+ Effectful.Error.Dynamic: runErrorNoCallStack :: HasCallStack => Eff (Error e : es) a -> Eff es (Either e a)
- Effectful.Error.Dynamic: runErrorNoCallStackWith :: (e -> Eff es a) -> Eff (Error e : es) a -> Eff es a
+ Effectful.Error.Dynamic: runErrorNoCallStackWith :: HasCallStack => (e -> Eff es a) -> Eff (Error e : es) a -> Eff es a
- Effectful.Error.Dynamic: runErrorWith :: (CallStack -> e -> Eff es a) -> Eff (Error e : es) a -> Eff es a
+ Effectful.Error.Dynamic: runErrorWith :: HasCallStack => (CallStack -> e -> Eff es a) -> Eff (Error e : es) a -> Eff es a
- Effectful.Error.Dynamic: throwError :: (HasCallStack, Error e :> es) => e -> Eff es a
+ Effectful.Error.Dynamic: throwError :: (HasCallStack, Error e :> es, Show e) => e -> Eff es a
- Effectful.Error.Static: catchError :: forall e es a. Error e :> es => Eff es a -> (CallStack -> e -> Eff es a) -> Eff es a
+ Effectful.Error.Static: catchError :: forall e es a. (HasCallStack, Error e :> es) => Eff es a -> (CallStack -> e -> Eff es a) -> Eff es a
- Effectful.Error.Static: data Error e :: Effect
+ Effectful.Error.Static: data Error (e :: Type) :: Effect
- Effectful.Error.Static: handleError :: forall e es a. Error e :> es => (CallStack -> e -> Eff es a) -> Eff es a -> Eff es a
+ Effectful.Error.Static: handleError :: forall e es a. (HasCallStack, Error e :> es) => (CallStack -> e -> Eff es a) -> Eff es a -> Eff es a
- Effectful.Error.Static: runError :: forall e es a. Eff (Error e : es) a -> Eff es (Either (CallStack, e) a)
+ Effectful.Error.Static: runError :: forall e es a. HasCallStack => Eff (Error e : es) a -> Eff es (Either (CallStack, e) a)
- Effectful.Error.Static: runErrorNoCallStack :: forall e es a. Eff (Error e : es) a -> Eff es (Either e a)
+ Effectful.Error.Static: runErrorNoCallStack :: forall e es a. HasCallStack => Eff (Error e : es) a -> Eff es (Either e a)
- Effectful.Error.Static: runErrorNoCallStackWith :: (e -> Eff es a) -> Eff (Error e : es) a -> Eff es a
+ Effectful.Error.Static: runErrorNoCallStackWith :: HasCallStack => (e -> Eff es a) -> Eff (Error e : es) a -> Eff es a
- Effectful.Error.Static: runErrorWith :: (CallStack -> e -> Eff es a) -> Eff (Error e : es) a -> Eff es a
+ Effectful.Error.Static: runErrorWith :: HasCallStack => (CallStack -> e -> Eff es a) -> Eff (Error e : es) a -> Eff es a
- Effectful.Error.Static: throwError :: forall e es a. (HasCallStack, Error e :> es) => e -> Eff es a
+ Effectful.Error.Static: throwError :: forall e es a. (HasCallStack, Error e :> es, Show e) => e -> Eff es a
- Effectful.Error.Static: tryError :: forall e es a. Error e :> es => Eff es a -> Eff es (Either (CallStack, e) a)
+ Effectful.Error.Static: tryError :: forall e es a. (HasCallStack, Error e :> es) => Eff es a -> Eff es (Either (CallStack, e) a)
- Effectful.Fail: runFail :: Eff (Fail : es) a -> Eff es (Either String a)
+ Effectful.Fail: runFail :: HasCallStack => Eff (Fail : es) a -> Eff es (Either String a)
- Effectful.Fail: runFailIO :: IOE :> es => Eff (Fail : es) a -> Eff es a
+ Effectful.Fail: runFailIO :: (HasCallStack, IOE :> es) => Eff (Fail : es) a -> Eff es a
- Effectful.Internal.Effect: class (xs :: [Effect]) `IsUnknownSuffixOf` (es :: [Effect])
+ Effectful.Internal.Effect: class (subEs :: [Effect]) `IsUnknownSuffixOf` (es :: [Effect])
- Effectful.Internal.Effect: class KnownPrefix es => Subset (xs :: [Effect]) (es :: [Effect])
+ Effectful.Internal.Effect: class KnownPrefix es => Subset (subEs :: [Effect]) (es :: [Effect])
- Effectful.Internal.Effect: reifyIndices :: Subset xs es => [Int]
+ Effectful.Internal.Effect: reifyIndices :: Subset subEs es => [Int]
- Effectful.Internal.Effect: subsetFullyKnown :: Subset xs es => Bool
+ Effectful.Internal.Effect: subsetFullyKnown :: Subset subEs es => Bool
- Effectful.Internal.Env: Env :: !Int -> !PrimArray Int -> !IORef' Storage -> Env (es :: [Effect])
+ Effectful.Internal.Env: Env :: !Int -> !PrimArray Ref -> !IORef' Storage -> Env (es :: [Effect])
- Effectful.Internal.Env: Storage :: !Int -> !Int -> !MutablePrimArray RealWorld Int -> !SmallMutableArray RealWorld Any -> !SmallMutableArray RealWorld Any -> Storage
+ Effectful.Internal.Env: Storage :: !Int -> !Version -> !MutablePrimArray RealWorld Version -> !SmallMutableArray RealWorld AnyEffect -> !SmallMutableArray RealWorld AnyRelinker -> Storage
- Effectful.Internal.Env: [Relinker] :: ((forall es. Env es -> IO (Env es)) -> rep e -> IO (rep e)) -> Relinker rep e
+ Effectful.Internal.Env: [Relinker] :: (HasCallStack => (forall es. Env es -> IO (Env es)) -> rep e -> IO (rep e)) -> Relinker rep e
- Effectful.Internal.Env: [envRefs] :: Env (es :: [Effect]) -> !PrimArray Int
+ Effectful.Internal.Env: [envRefs] :: Env (es :: [Effect]) -> !PrimArray Ref
- Effectful.Internal.Env: [stEffects] :: Storage -> !SmallMutableArray RealWorld Any
+ Effectful.Internal.Env: [stEffects] :: Storage -> !SmallMutableArray RealWorld AnyEffect
- Effectful.Internal.Env: [stRelinkers] :: Storage -> !SmallMutableArray RealWorld Any
+ Effectful.Internal.Env: [stRelinkers] :: Storage -> !SmallMutableArray RealWorld AnyRelinker
- Effectful.Internal.Env: [stVersion] :: Storage -> !Int
+ Effectful.Internal.Env: [stVersion] :: Storage -> !Version
- Effectful.Internal.Env: [stVersions] :: Storage -> !MutablePrimArray RealWorld Int
+ Effectful.Internal.Env: [stVersions] :: Storage -> !MutablePrimArray RealWorld Version
- Effectful.Internal.Env: cloneEnv :: Env es -> IO (Env es)
+ Effectful.Internal.Env: cloneEnv :: HasCallStack => Env es -> IO (Env es)
- Effectful.Internal.Env: consEnv :: EffectRep (DispatchOf e) e -> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env (e : es))
+ Effectful.Internal.Env: consEnv :: HasCallStack => EffectRep (DispatchOf e) e -> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env (e : es))
- Effectful.Internal.Env: emptyEnv :: IO (Env '[])
+ Effectful.Internal.Env: emptyEnv :: HasCallStack => IO (Env '[])
- Effectful.Internal.Env: getEnv :: forall e es. e :> es => Env es -> IO (EffectRep (DispatchOf e) e)
+ Effectful.Internal.Env: getEnv :: forall e es. (HasCallStack, e :> es) => Env es -> IO (EffectRep (DispatchOf e) e)
- Effectful.Internal.Env: injectEnv :: forall xs es. Subset xs es => Env es -> IO (Env xs)
+ Effectful.Internal.Env: injectEnv :: forall subEs es. Subset subEs es => Env es -> IO (Env subEs)
- Effectful.Internal.Env: modifyEnv :: forall e es. e :> es => Env es -> (EffectRep (DispatchOf e) e -> IO (EffectRep (DispatchOf e) e)) -> IO ()
+ Effectful.Internal.Env: modifyEnv :: forall e es. (HasCallStack, e :> es) => Env es -> (EffectRep (DispatchOf e) e -> EffectRep (DispatchOf e) e) -> IO ()
- Effectful.Internal.Env: putEnv :: forall e es. e :> es => Env es -> EffectRep (DispatchOf e) e -> IO ()
+ Effectful.Internal.Env: putEnv :: forall e es. (HasCallStack, e :> es) => Env es -> EffectRep (DispatchOf e) e -> IO ()
- Effectful.Internal.Env: replaceEnv :: forall e es. e :> es => EffectRep (DispatchOf e) e -> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env es)
+ Effectful.Internal.Env: replaceEnv :: forall e es. (HasCallStack, e :> es) => EffectRep (DispatchOf e) e -> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env es)
- Effectful.Internal.Env: restoreEnv :: Env es -> Env es -> IO ()
+ Effectful.Internal.Env: restoreEnv :: HasCallStack => Env es -> Env es -> IO ()
- Effectful.Internal.Env: stateEnv :: forall e es a. e :> es => Env es -> (EffectRep (DispatchOf e) e -> IO (a, EffectRep (DispatchOf e) e)) -> IO a
+ Effectful.Internal.Env: stateEnv :: forall e es a. (HasCallStack, e :> es) => Env es -> (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e)) -> IO a
- Effectful.Internal.Env: unconsEnv :: Env (e : es) -> IO ()
+ Effectful.Internal.Env: unconsEnv :: HasCallStack => Env (e : es) -> IO ()
- Effectful.Internal.Env: unreplaceEnv :: forall e es. e :> es => Env es -> IO ()
+ Effectful.Internal.Env: unreplaceEnv :: forall e es. (HasCallStack, e :> es) => Env es -> IO ()
- Effectful.Internal.Monad: class KnownPrefix es => Subset (xs :: [Effect]) (es :: [Effect])
+ Effectful.Internal.Monad: class KnownPrefix es => Subset (subEs :: [Effect]) (es :: [Effect])
- Effectful.Internal.Monad: evalStaticRep :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es a
+ Effectful.Internal.Monad: evalStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es a
- Effectful.Internal.Monad: execStaticRep :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (StaticRep e)
+ Effectful.Internal.Monad: execStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (StaticRep e)
- Effectful.Internal.Monad: getStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => Eff es (StaticRep e)
+ Effectful.Internal.Monad: getStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => Eff es (StaticRep e)
- Effectful.Internal.Monad: inject :: Subset xs es => Eff xs a -> Eff es a
+ Effectful.Internal.Monad: inject :: Subset subEs es => Eff subEs a -> Eff es a
- Effectful.Internal.Monad: localStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
+ Effectful.Internal.Monad: localStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
- Effectful.Internal.Monad: putStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => StaticRep e -> Eff es ()
+ Effectful.Internal.Monad: putStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => StaticRep e -> Eff es ()
- Effectful.Internal.Monad: runEff :: Eff '[IOE] a -> IO a
+ Effectful.Internal.Monad: runEff :: HasCallStack => Eff '[IOE] a -> IO a
- Effectful.Internal.Monad: runHandler :: DispatchOf e ~ Dynamic => Handler e -> Eff (e : es) a -> Eff es a
+ Effectful.Internal.Monad: runHandler :: (HasCallStack, DispatchOf e ~ Dynamic) => Handler e -> Eff (e : es) a -> Eff es a
- Effectful.Internal.Monad: runPrim :: IOE :> es => Eff (Prim : es) a -> Eff es a
+ Effectful.Internal.Monad: runPrim :: (HasCallStack, IOE :> es) => Eff (Prim : es) a -> Eff es a
- Effectful.Internal.Monad: runPureEff :: Eff '[] a -> a
+ Effectful.Internal.Monad: runPureEff :: HasCallStack => Eff '[] a -> a
- Effectful.Internal.Monad: runStaticRep :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (a, StaticRep e)
+ Effectful.Internal.Monad: runStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (a, StaticRep e)
- Effectful.Internal.Monad: stateStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> (a, StaticRep e)) -> Eff es a
+ Effectful.Internal.Monad: stateStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> (a, StaticRep e)) -> Eff es a
- Effectful.Internal.Monad: stateStaticRepM :: (DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> Eff es (a, StaticRep e)) -> Eff es a
+ Effectful.Internal.Monad: stateStaticRepM :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> Eff es (a, StaticRep e)) -> Eff es a
- Effectful.Internal.Monad: type EffectHandler e es = forall a localEs. (HasCallStack, e :> localEs) => -- | Capture of the local environment for handling local 'Eff' computations -- when @e@ is a higher order effect. LocalEnv localEs es -> -- | The effect performed in the local environment. e (Eff localEs) a -> Eff es a
+ Effectful.Internal.Monad: type EffectHandler (e :: Effect) (es :: [Effect]) = forall a localEs. (HasCallStack, e :> localEs) => -- | Capture of the local environment for handling local 'Eff' computations -- when @e@ is a higher order effect. LocalEnv localEs es -> -- | The operation. e (Eff localEs) a -> Eff es a
- Effectful.Labeled: labeled :: forall label e es a. Labeled label e :> es => Eff (e : es) a -> Eff es a
+ Effectful.Labeled: labeled :: forall label e es a. (HasCallStack, Labeled label e :> es) => Eff (e : es) a -> Eff es a
- Effectful.Labeled: runLabeled :: forall label e es a b. (Eff (e : es) a -> Eff es b) -> Eff (Labeled label e : es) a -> Eff es b
+ Effectful.Labeled: runLabeled :: forall label e es a b. HasCallStack => (Eff (e : es) a -> Eff es b) -> Eff (Labeled label e : es) a -> Eff es b
- Effectful.NonDet: runNonDet :: OnEmptyPolicy -> Eff (NonDet : es) a -> Eff es (Either CallStack a)
+ Effectful.NonDet: runNonDet :: HasCallStack => OnEmptyPolicy -> Eff (NonDet : es) a -> Eff es (Either CallStack a)
- Effectful.Prim: runPrim :: IOE :> es => Eff (Prim : es) a -> Eff es a
+ Effectful.Prim: runPrim :: (HasCallStack, IOE :> es) => Eff (Prim : es) a -> Eff es a
- Effectful.Provider: provide :: Provider e () f :> es => Eff (e : es) a -> Eff es (f a)
+ Effectful.Provider: provide :: (HasCallStack, Provider e () f :> es) => Eff (e : es) a -> Eff es (f a)
- Effectful.Provider: provideWith :: Provider e input f :> es => input -> Eff (e : es) a -> Eff es (f a)
+ Effectful.Provider: provideWith :: (HasCallStack, Provider e input f :> es) => input -> Eff (e : es) a -> Eff es (f a)
- Effectful.Provider: provideWith_ :: Provider_ e input :> es => input -> Eff (e : es) a -> Eff es a
+ Effectful.Provider: provideWith_ :: (HasCallStack, Provider_ e input :> es) => input -> Eff (e : es) a -> Eff es a
- Effectful.Provider: provide_ :: Provider_ e () :> es => Eff (e : es) a -> Eff es a
+ Effectful.Provider: provide_ :: (HasCallStack, Provider_ e () :> es) => Eff (e : es) a -> Eff es a
- Effectful.Provider: runProvider :: (forall r. input -> Eff (e : es) r -> Eff es (f r)) -> Eff (Provider e input f : es) a -> Eff es a
+ Effectful.Provider: runProvider :: HasCallStack => (forall r. HasCallStack => input -> Eff (e : es) r -> Eff es (f r)) -> Eff (Provider e input f : es) a -> Eff es a
- Effectful.Provider: runProvider_ :: (forall r. input -> Eff (e : es) r -> Eff es r) -> Eff (Provider_ e input : es) a -> Eff es a
+ Effectful.Provider: runProvider_ :: HasCallStack => (forall r. HasCallStack => input -> Eff (e : es) r -> Eff es r) -> Eff (Provider_ e input : es) a -> Eff es a
- Effectful.Provider.List: data ProviderList (effects :: [Effect]) (input :: Type) (f :: Type -> Type) :: Effect
+ Effectful.Provider.List: data ProviderList (providedEs :: [Effect]) (input :: Type) (f :: Type -> Type) :: Effect
- Effectful.Provider.List: provideList :: forall effs f es a. ProviderList effs () f :> es => Eff (effs ++ es) a -> Eff es (f a)
+ Effectful.Provider.List: provideList :: forall providedEs f es a. (HasCallStack, ProviderList providedEs () f :> es) => Eff (providedEs ++ es) a -> Eff es (f a)
- Effectful.Provider.List: provideListWith :: forall effs input f es a. ProviderList effs input f :> es => input -> Eff (effs ++ es) a -> Eff es (f a)
+ Effectful.Provider.List: provideListWith :: forall providedEs input f es a. (HasCallStack, ProviderList providedEs input f :> es) => input -> Eff (providedEs ++ es) a -> Eff es (f a)
- Effectful.Provider.List: provideListWith_ :: forall effs input es a. ProviderList_ effs input :> es => input -> Eff (effs ++ es) a -> Eff es a
+ Effectful.Provider.List: provideListWith_ :: forall providedEs input es a. (HasCallStack, ProviderList_ providedEs input :> es) => input -> Eff (providedEs ++ es) a -> Eff es a
- Effectful.Provider.List: provideList_ :: forall effs es a. ProviderList_ effs () :> es => Eff (effs ++ es) a -> Eff es a
+ Effectful.Provider.List: provideList_ :: forall providedEs es a. (HasCallStack, ProviderList_ providedEs () :> es) => Eff (providedEs ++ es) a -> Eff es a
- Effectful.Provider.List: runProviderList :: KnownEffects effs => (forall r. input -> Eff (effs ++ es) r -> Eff es (f r)) -> Eff (ProviderList effs input f : es) a -> Eff es a
+ Effectful.Provider.List: runProviderList :: (HasCallStack, KnownEffects providedEs) => (forall r. HasCallStack => input -> Eff (providedEs ++ es) r -> Eff es (f r)) -> Eff (ProviderList providedEs input f : es) a -> Eff es a
- Effectful.Provider.List: runProviderList_ :: KnownEffects effs => (forall r. input -> Eff (effs ++ es) r -> Eff es r) -> Eff (ProviderList_ effs input : es) a -> Eff es a
+ Effectful.Provider.List: runProviderList_ :: (HasCallStack, KnownEffects providedEs) => (forall r. HasCallStack => input -> Eff (providedEs ++ es) r -> Eff es r) -> Eff (ProviderList_ providedEs input : es) a -> Eff es a
- Effectful.Provider.List: type ProviderList_ effs input = ProviderList effs input Identity
+ Effectful.Provider.List: type ProviderList_ providedEs input = ProviderList providedEs input Identity
- Effectful.Reader.Dynamic: runReader :: r -> Eff (Reader r : es) a -> Eff es a
+ Effectful.Reader.Dynamic: runReader :: HasCallStack => r -> Eff (Reader r : es) a -> Eff es a
- Effectful.Reader.Dynamic: withReader :: (r1 -> r2) -> Eff (Reader r2 : es) a -> Eff (Reader r1 : es) a
+ Effectful.Reader.Dynamic: withReader :: HasCallStack => (r1 -> r2) -> Eff (Reader r2 : es) a -> Eff (Reader r1 : es) a
- Effectful.Reader.Static: ask :: Reader r :> es => Eff es r
+ Effectful.Reader.Static: ask :: (HasCallStack, Reader r :> es) => Eff es r
- Effectful.Reader.Static: asks :: Reader r :> es => (r -> a) -> Eff es a
+ Effectful.Reader.Static: asks :: (HasCallStack, Reader r :> es) => (r -> a) -> Eff es a
- Effectful.Reader.Static: data Reader r :: Effect
+ Effectful.Reader.Static: data Reader (r :: Type) :: Effect
- Effectful.Reader.Static: local :: Reader r :> es => (r -> r) -> Eff es a -> Eff es a
+ Effectful.Reader.Static: local :: (HasCallStack, Reader r :> es) => (r -> r) -> Eff es a -> Eff es a
- Effectful.Reader.Static: runReader :: r -> Eff (Reader r : es) a -> Eff es a
+ Effectful.Reader.Static: runReader :: HasCallStack => r -> Eff (Reader r : es) a -> Eff es a
- Effectful.Reader.Static: withReader :: (r1 -> r2) -> Eff (Reader r2 : es) a -> Eff (Reader r1 : es) a
+ Effectful.Reader.Static: withReader :: HasCallStack => (r1 -> r2) -> Eff (Reader r2 : es) a -> Eff (Reader r1 : es) a
- Effectful.State.Dynamic: evalStateLocal :: s -> Eff (State s : es) a -> Eff es a
+ Effectful.State.Dynamic: evalStateLocal :: HasCallStack => s -> Eff (State s : es) a -> Eff es a
- Effectful.State.Dynamic: evalStateShared :: s -> Eff (State s : es) a -> Eff es a
+ Effectful.State.Dynamic: evalStateShared :: HasCallStack => s -> Eff (State s : es) a -> Eff es a
- Effectful.State.Dynamic: execStateLocal :: s -> Eff (State s : es) a -> Eff es s
+ Effectful.State.Dynamic: execStateLocal :: HasCallStack => s -> Eff (State s : es) a -> Eff es s
- Effectful.State.Dynamic: execStateShared :: s -> Eff (State s : es) a -> Eff es s
+ Effectful.State.Dynamic: execStateShared :: HasCallStack => s -> Eff (State s : es) a -> Eff es s
- Effectful.State.Dynamic: runStateLocal :: s -> Eff (State s : es) a -> Eff es (a, s)
+ Effectful.State.Dynamic: runStateLocal :: HasCallStack => s -> Eff (State s : es) a -> Eff es (a, s)
- Effectful.State.Dynamic: runStateShared :: s -> Eff (State s : es) a -> Eff es (a, s)
+ Effectful.State.Dynamic: runStateShared :: HasCallStack => s -> Eff (State s : es) a -> Eff es (a, s)
- Effectful.State.Static.Local: data State s :: Effect
+ Effectful.State.Static.Local: data State (s :: Type) :: Effect
- Effectful.State.Static.Local: evalState :: s -> Eff (State s : es) a -> Eff es a
+ Effectful.State.Static.Local: evalState :: HasCallStack => s -> Eff (State s : es) a -> Eff es a
- Effectful.State.Static.Local: execState :: s -> Eff (State s : es) a -> Eff es s
+ Effectful.State.Static.Local: execState :: HasCallStack => s -> Eff (State s : es) a -> Eff es s
- Effectful.State.Static.Local: get :: State s :> es => Eff es s
+ Effectful.State.Static.Local: get :: (HasCallStack, State s :> es) => Eff es s
- Effectful.State.Static.Local: gets :: State s :> es => (s -> a) -> Eff es a
+ Effectful.State.Static.Local: gets :: (HasCallStack, State s :> es) => (s -> a) -> Eff es a
- Effectful.State.Static.Local: modify :: State s :> es => (s -> s) -> Eff es ()
+ Effectful.State.Static.Local: modify :: (HasCallStack, State s :> es) => (s -> s) -> Eff es ()
- Effectful.State.Static.Local: modifyM :: State s :> es => (s -> Eff es s) -> Eff es ()
+ Effectful.State.Static.Local: modifyM :: (HasCallStack, State s :> es) => (s -> Eff es s) -> Eff es ()
- Effectful.State.Static.Local: put :: State s :> es => s -> Eff es ()
+ Effectful.State.Static.Local: put :: (HasCallStack, State s :> es) => s -> Eff es ()
- Effectful.State.Static.Local: runState :: s -> Eff (State s : es) a -> Eff es (a, s)
+ Effectful.State.Static.Local: runState :: HasCallStack => s -> Eff (State s : es) a -> Eff es (a, s)
- Effectful.State.Static.Local: state :: State s :> es => (s -> (a, s)) -> Eff es a
+ Effectful.State.Static.Local: state :: (HasCallStack, State s :> es) => (s -> (a, s)) -> Eff es a
- Effectful.State.Static.Local: stateM :: State s :> es => (s -> Eff es (a, s)) -> Eff es a
+ Effectful.State.Static.Local: stateM :: (HasCallStack, State s :> es) => (s -> Eff es (a, s)) -> Eff es a
- Effectful.State.Static.Shared: data State s :: Effect
+ Effectful.State.Static.Shared: data State (s :: Type) :: Effect
- Effectful.State.Static.Shared: evalState :: s -> Eff (State s : es) a -> Eff es a
+ Effectful.State.Static.Shared: evalState :: HasCallStack => s -> Eff (State s : es) a -> Eff es a
- Effectful.State.Static.Shared: evalStateMVar :: MVar s -> Eff (State s : es) a -> Eff es a
+ Effectful.State.Static.Shared: evalStateMVar :: HasCallStack => MVar' s -> Eff (State s : es) a -> Eff es a
- Effectful.State.Static.Shared: execState :: s -> Eff (State s : es) a -> Eff es s
+ Effectful.State.Static.Shared: execState :: HasCallStack => s -> Eff (State s : es) a -> Eff es s
- Effectful.State.Static.Shared: execStateMVar :: MVar s -> Eff (State s : es) a -> Eff es s
+ Effectful.State.Static.Shared: execStateMVar :: HasCallStack => MVar' s -> Eff (State s : es) a -> Eff es s
- Effectful.State.Static.Shared: get :: State s :> es => Eff es s
+ Effectful.State.Static.Shared: get :: (HasCallStack, State s :> es) => Eff es s
- Effectful.State.Static.Shared: gets :: State s :> es => (s -> a) -> Eff es a
+ Effectful.State.Static.Shared: gets :: (HasCallStack, State s :> es) => (s -> a) -> Eff es a
- Effectful.State.Static.Shared: modify :: State s :> es => (s -> s) -> Eff es ()
+ Effectful.State.Static.Shared: modify :: (HasCallStack, State s :> es) => (s -> s) -> Eff es ()
- Effectful.State.Static.Shared: modifyM :: State s :> es => (s -> Eff es s) -> Eff es ()
+ Effectful.State.Static.Shared: modifyM :: (HasCallStack, State s :> es) => (s -> Eff es s) -> Eff es ()
- Effectful.State.Static.Shared: put :: State s :> es => s -> Eff es ()
+ Effectful.State.Static.Shared: put :: (HasCallStack, State s :> es) => s -> Eff es ()
- Effectful.State.Static.Shared: runState :: s -> Eff (State s : es) a -> Eff es (a, s)
+ Effectful.State.Static.Shared: runState :: HasCallStack => s -> Eff (State s : es) a -> Eff es (a, s)
- Effectful.State.Static.Shared: runStateMVar :: MVar s -> Eff (State s : es) a -> Eff es (a, s)
+ Effectful.State.Static.Shared: runStateMVar :: HasCallStack => MVar' s -> Eff (State s : es) a -> Eff es (a, s)
- Effectful.State.Static.Shared: state :: State s :> es => (s -> (a, s)) -> Eff es a
+ Effectful.State.Static.Shared: state :: (HasCallStack, State s :> es) => (s -> (a, s)) -> Eff es a
- Effectful.State.Static.Shared: stateM :: State s :> es => (s -> Eff es (a, s)) -> Eff es a
+ Effectful.State.Static.Shared: stateM :: (HasCallStack, State s :> es) => (s -> Eff es (a, s)) -> Eff es a
- Effectful.Writer.Dynamic: execWriterLocal :: Monoid w => Eff (Writer w : es) a -> Eff es w
+ Effectful.Writer.Dynamic: execWriterLocal :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es w
- Effectful.Writer.Dynamic: execWriterShared :: Monoid w => Eff (Writer w : es) a -> Eff es w
+ Effectful.Writer.Dynamic: execWriterShared :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es w
- Effectful.Writer.Dynamic: runWriterLocal :: Monoid w => Eff (Writer w : es) a -> Eff es (a, w)
+ Effectful.Writer.Dynamic: runWriterLocal :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es (a, w)
- Effectful.Writer.Dynamic: runWriterShared :: Monoid w => Eff (Writer w : es) a -> Eff es (a, w)
+ Effectful.Writer.Dynamic: runWriterShared :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es (a, w)
- Effectful.Writer.Static.Local: data Writer w :: Effect
+ Effectful.Writer.Static.Local: data Writer (w :: Type) :: Effect
- Effectful.Writer.Static.Local: execWriter :: Monoid w => Eff (Writer w : es) a -> Eff es w
+ Effectful.Writer.Static.Local: execWriter :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es w
- Effectful.Writer.Static.Local: listen :: (Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w)
+ Effectful.Writer.Static.Local: listen :: (HasCallStack, Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w)
- Effectful.Writer.Static.Local: listens :: (Writer w :> es, Monoid w) => (w -> b) -> Eff es a -> Eff es (a, b)
+ Effectful.Writer.Static.Local: listens :: (HasCallStack, Writer w :> es, Monoid w) => (w -> b) -> Eff es a -> Eff es (a, b)
- Effectful.Writer.Static.Local: runWriter :: Monoid w => Eff (Writer w : es) a -> Eff es (a, w)
+ Effectful.Writer.Static.Local: runWriter :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es (a, w)
- Effectful.Writer.Static.Local: tell :: (Writer w :> es, Monoid w) => w -> Eff es ()
+ Effectful.Writer.Static.Local: tell :: (HasCallStack, Writer w :> es, Monoid w) => w -> Eff es ()
- Effectful.Writer.Static.Shared: data Writer w :: Effect
+ Effectful.Writer.Static.Shared: data Writer (w :: Type) :: Effect
- Effectful.Writer.Static.Shared: execWriter :: Monoid w => Eff (Writer w : es) a -> Eff es w
+ Effectful.Writer.Static.Shared: execWriter :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es w
- Effectful.Writer.Static.Shared: listen :: (Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w)
+ Effectful.Writer.Static.Shared: listen :: (HasCallStack, Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w)
- Effectful.Writer.Static.Shared: listens :: (Writer w :> es, Monoid w) => (w -> b) -> Eff es a -> Eff es (a, b)
+ Effectful.Writer.Static.Shared: listens :: (HasCallStack, Writer w :> es, Monoid w) => (w -> b) -> Eff es a -> Eff es (a, b)
- Effectful.Writer.Static.Shared: runWriter :: Monoid w => Eff (Writer w : es) a -> Eff es (a, w)
+ Effectful.Writer.Static.Shared: runWriter :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es (a, w)
- Effectful.Writer.Static.Shared: tell :: (Writer w :> es, Monoid w) => w -> Eff es ()
+ Effectful.Writer.Static.Shared: tell :: (HasCallStack, Writer w :> es, Monoid w) => w -> Eff es ()

Files

CHANGELOG.md view
@@ -1,3 +1,39 @@+# effectful-core-2.4.0.0 (2024-10-08)+* Add utility functions for handling effects that take the effect handler as the+  last parameter to `Effectful.Dispatch.Dynamic`.+* Add utility functions for handling first order effects to+  `Effectful.Dispatch.Dynamic`.+* Improve `Effectful.Labeled`, add `Effectful.Labeled.Error`,+  `Effectful.Labeled.Reader`, `Effectful.Labeled.State` and+  `Effectful.Labeled.Writer`.+* Add `throwErrorWith` and `throwError_` to `Effectful.Error.Static` and+  `Effectful.Error.Dynamic`.+* Add `HasCallStack` constraints where appropriate for better debugging+  experience.+* Add a `SeqForkUnlift` strategy to support running unlifting functions outside+  of the scope of effects they capture.+* Add `Effectful.Exception` with appropriate re-exports from the+  `safe-exceptions` library.+* **Bugfixes**:+  - Ensure that a `LocalEnv` is only used in a thread it belongs to.+  - Properly roll back changes made to the environment when `OnEmptyRollback`+    policy for the `NonDet` effect is selected.+  - Fix a bug in `stateM` and `modifyM` of thread local `State` effect that+    might've caused dropped state updates+    ([#237](https://github.com/haskell-effectful/effectful/issues/237)).+* **Breaking changes**:+  - `localSeqLend`, `localLend`, `localSeqBorrow` and `localBorrow` now take a+    list of effects instead of a single one.+  - `Effectful.Error.Static.throwError` now requires the error type to have a+    `Show` constraint. If this is not the case for some of your error types, use+    `throwError_` for them.+  - `ThrowError` operation from the dynamic version of the `Error` effect was+    replaced with `ThrowErrorWith`.+  - `stateEnv` and `modifyEnv` now take pure modification functions. If you rely+    on their old forms, switch to a combination of `getEnv` and `putEnv`.+  - `runStateMVar`, `evalStateMVar` and `execStateMVar` now take a strict+    `MVar'` from the `strict-mutable-base` package.+ # effectful-core-2.3.1.0 (2024-06-07) * Drop support for GHC 8.8. * Remove inaccurate information from the `Show` instance of `ErrorWrapper`.
effectful-core.cabal view
@@ -1,7 +1,7 @@ cabal-version:      3.0 build-type:         Simple name:               effectful-core-version:            2.3.1.0+version:            2.4.0.0 license:            BSD-3-Clause license-file:       LICENSE category:           Control@@ -29,7 +29,10 @@   location: https://github.com/haskell-effectful/effectful.git  common language-    ghc-options:        -Wall -Wcompat -Wno-unticked-promoted-constructors+    ghc-options:        -Wall+                        -Wcompat+                        -Wno-unticked-promoted-constructors+                        -Wmissing-deriving-strategies                         -Werror=prepositive-qualified-module      default-language:   Haskell2010@@ -39,6 +42,7 @@                         DataKinds                         DeriveFunctor                         DeriveGeneric+                        DerivingStrategies                         FlexibleContexts                         FlexibleInstances                         GADTs@@ -47,6 +51,7 @@                         LambdaCase                         MultiParamTypeClasses                         NoStarIsType+                        PolyKinds                         RankNTypes                         RoleAnnotations                         ScopedTypeVariables@@ -63,9 +68,12 @@      build-depends:    base                >= 4.14      && < 5                     , containers          >= 0.6+                    , deepseq             >= 1.2                     , exceptions          >= 0.10.4                     , monad-control       >= 1.0.3                     , primitive           >= 0.7.3.0+                    , safe-exceptions     >= 0.1.7.2+                    , strict-mutable-base >= 1.1.0.0                     , transformers-base   >= 0.4.6                     , unliftio-core       >= 0.2.0.1 @@ -81,6 +89,7 @@                      Effectful.Dispatch.Static.Unsafe                      Effectful.Error.Dynamic                      Effectful.Error.Static+                     Effectful.Exception                      Effectful.Fail                      Effectful.Internal.Effect                      Effectful.Internal.Env@@ -88,6 +97,10 @@                      Effectful.Internal.Unlift                      Effectful.Internal.Utils                      Effectful.Labeled+                     Effectful.Labeled.Error+                     Effectful.Labeled.Reader+                     Effectful.Labeled.State+                     Effectful.Labeled.Writer                      Effectful.NonDet                      Effectful.Prim                      Effectful.Provider
src/Effectful.hs view
@@ -148,7 +148,7 @@ -- -- These libraries can trivially be used with the 'Eff' monad since it provides -- typical instances that these libraries require the underlying monad to have,--- such as t'Control.Monad.Catch.MonadMask' or 'MonadUnliftIO'.+-- such as t'Effectful.Exception.MonadMask' or 'MonadUnliftIO'. -- -- In case the 'Eff' monad doesn't provide a specific instance out of the box, -- it can be supplied via an effect. As an example see how the instance of@@ -199,8 +199,8 @@ -- -- As an example, consider the following monad: ----- >>> import qualified Control.Monad.State as T--- >>> import qualified Control.Monad.Except as T+-- >>> import Control.Monad.State qualified as T+-- >>> import Control.Monad.Except qualified as T -- -- >>> data HandlerState -- >>> data HandlerError
src/Effectful/Dispatch/Dynamic.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ImplicitParams #-} {-# LANGUAGE UndecidableInstances #-} -- | Dynamically dispatched effects.@@ -23,9 +24,13 @@     -- * Handling effects   , EffectHandler   , interpret+  , interpretWith   , reinterpret+  , reinterpretWith   , interpose+  , interposeWith   , impose+  , imposeWith      -- ** Handling local 'Eff' computations   , LocalEnv@@ -52,13 +57,23 @@   , localSeqBorrow   , localBorrow   , SharedSuffix+  , KnownSubset +    -- ** Utils for first order effects+  , EffectHandler_+  , interpret_+  , interpretWith_+  , reinterpret_+  , reinterpretWith_+  , interpose_+  , interposeWith_+  , impose_+  , imposeWith_+     -- * Re-exports   , HasCallStack   ) where -import Control.Monad-import Control.Monad.IO.Unlift import Data.Primitive.PrimArray import GHC.Stack (HasCallStack) import GHC.TypeLits@@ -138,11 +153,9 @@ -- The following defines an 'EffectHandler' that reads and writes files from the -- drive: ----- >>> import Control.Exception (IOException)--- >>> import Control.Monad.Catch (catch)--- >>> import qualified System.IO as IO--- -- >>> import Effectful.Error.Static+-- >>> import Effectful.Exception+-- >>> import System.IO qualified as IO -- -- >>> newtype FsError = FsError String deriving Show --@@ -155,7 +168,7 @@ --    ReadFile path           -> adapt $ IO.readFile path --    WriteFile path contents -> adapt $ IO.writeFile path contents --    where---      adapt m = liftIO m `catch` \(e::IOException) -> throwError . FsError $ show e+--      adapt m = liftIO m `catchIO` \e -> throwError . FsError $ show e -- :} -- -- Here, we use 'interpret' and simply execute corresponding 'IO' actions for@@ -164,8 +177,7 @@ -- On the other hand, maybe there is a situation in which instead of interacting -- with the outside world, a pure, in-memory storage is preferred: ----- >>> import qualified Data.Map.Strict as M---+-- >>> import Data.Map.Strict qualified as M -- >>> import Effectful.State.Static.Local -- -- >>> :{@@ -212,6 +224,9 @@ -- -- If an effect makes use of the @m@ parameter, it is a /higher order effect/. --+-- /Note:/ for handling first order effects you can use 'interpret_' or+-- 'reinterpret_' whose 'EffectHandler_' doesn't take the 'LocalEnv' parameter.+-- -- Interpretation of higher order effects is slightly more involving. To see -- why, let's consider the @Profiling@ effect for logging how much time a -- specific action took to run:@@ -343,7 +358,7 @@ -- -- >>> :{ --   runDummyRNG :: Eff (RNG : es) a -> Eff es a---   runDummyRNG = interpret $ \_ -> \case+--   runDummyRNG = interpret_ $ \case --     RandomInt -> pure 55 -- :} --@@ -381,9 +396,8 @@ -- ...    for functional dependency: ‘m -> i’... -- ... ----- However, there exists a [dirty--- trick](https://www.youtube.com/watch?v=ZXtdd8e7CQQ) for bypassing the--- coverage condition, i.e. including the instance head in the context:+-- However, there exists a trick for bypassing the coverage condition,+-- i.e. including the instance head in its context: -- -- >>> :{ --   instance (MonadInput i (Eff es), Reader i :> es) => MonadInput i (Eff es) where@@ -408,7 +422,7 @@ -- /Note:/ 'interpret' can be turned into a 'reinterpret' with the use of -- 'inject'. interpret-  :: DispatchOf e ~ Dynamic+  :: (HasCallStack, DispatchOf e ~ Dynamic)   => EffectHandler e es   -- ^ The effect handler.   -> Eff (e : es) a@@ -418,11 +432,22 @@   where     mkHandler es = Handler es (let ?callStack = thawCallStack ?callStack in handler) +-- | 'interpret' with the effect handler as the last argument.+--+-- @since 2.4.0.0+interpretWith+  :: (HasCallStack, DispatchOf e ~ Dynamic)+  => Eff (e : es) a+  -> EffectHandler e es+  -- ^ The effect handler.+  -> Eff      es  a+interpretWith m handler = interpret handler m+ -- | Interpret an effect using other, private effects. -- -- @'interpret' ≡ 'reinterpret' 'id'@ reinterpret-  :: DispatchOf e ~ Dynamic+  :: (HasCallStack, DispatchOf e ~ Dynamic)   => (Eff handlerEs a -> Eff es b)   -- ^ Introduction of effects encapsulated within the handler.   -> EffectHandler e handlerEs@@ -435,6 +460,19 @@   where     mkHandler es = Handler es (let ?callStack = thawCallStack ?callStack in handler) +-- | 'reinterpret' with the effect handler as the last argument.+--+-- @since 2.4.0.0+reinterpretWith+  :: (HasCallStack, DispatchOf e ~ Dynamic)+  => (Eff handlerEs a -> Eff es b)+  -- ^ Introduction of effects encapsulated within the handler.+  -> Eff (e : es) a+  -> EffectHandler e handlerEs+  -- ^ The effect handler.+  -> Eff      es  b+reinterpretWith runHandlerEs m handler = reinterpret runHandlerEs handler m+ -- | Replace the handler of an existing effect with a new one. -- -- /Note:/ this function allows for augmenting handlers with a new functionality@@ -442,29 +480,70 @@ -- -- >>> :{ --   data E :: Effect where---     Op :: E m ()+--     Op1 :: E m ()+--     Op2 :: E m () --   type instance DispatchOf E = Dynamic -- :} -- -- >>> :{ --   runE :: IOE :> es => Eff (E : es) a -> Eff es a---   runE = interpret $ \_ Op -> liftIO (putStrLn "op")+--   runE = interpret_ $ \case+--     Op1 -> liftIO (putStrLn "op1")+--     Op2 -> liftIO (putStrLn "op2") -- :} ----- >>> runEff . runE $ send Op--- op+-- >>> runEff . runE $ send Op1 >> send Op2+-- op1+-- op2 -- -- >>> :{---   augmentE :: (E :> es, IOE :> es) => Eff es a -> Eff es a---   augmentE = interpose $ \_ Op -> liftIO (putStrLn "augmented op") >> send Op+--   augmentOp2 :: (E :> es, IOE :> es) => Eff es a -> Eff es a+--   augmentOp2 = interpose_ $ \case+--     Op1 -> send Op1+--     Op2 -> liftIO (putStrLn "augmented op2") >> send Op2 -- :} ----- >>> runEff . runE . augmentE $ send Op--- augmented op--- op+-- >>> runEff . runE . augmentOp2 $ send Op1 >> send Op2+-- op1+-- augmented op2+-- op2 --+-- /Note:/ when using 'interpose' to modify only specific operations of the+-- effect, your first instinct might be to match on them, then handle the rest+-- with a generic match. Unfortunately, this doesn't work out of the box:+--+-- >>> :{+--   genericAugmentOp2 :: (E :> es, IOE :> es) => Eff es a -> Eff es a+--   genericAugmentOp2 = interpose_ $ \case+--     Op2 -> liftIO (putStrLn "augmented op2") >> send Op2+--     op  -> send op+-- :}+-- ...+-- ...Couldn't match type ‘localEs’ with ‘es’+-- ...+--+-- This is because within the generic match, 'send' expects @Op (Eff es) a@, but+-- @op@ has a type @Op (Eff localEs) a@. If the effect in question is first+-- order (i.e. its @m@ type parameter is phantom), you can use 'coerce':+--+-- >>> import Data.Coerce+-- >>> :{+--   genericAugmentOp2 :: (E :> es, IOE :> es) => Eff es a -> Eff es a+--   genericAugmentOp2 = interpose_ $ \case+--     Op2 -> liftIO (putStrLn "augmented op2") >> send Op2+--     op  -> send @E (coerce op)+-- :}+--+-- >>> runEff . runE . genericAugmentOp2 $ send Op1 >> send Op2+-- op1+-- augmented op2+-- op2+--+-- On the other hand, when dealing with higher order effects you need to pattern+-- match on each operation and unlift where necessary.+-- interpose-  :: forall e es a. (DispatchOf e ~ Dynamic, e :> es)+  :: forall e es a. (HasCallStack, DispatchOf e ~ Dynamic, e :> es)   => EffectHandler e es   -- ^ The effect handler.   -> Eff es a@@ -489,12 +568,23 @@   where     mkHandler es = Handler es (let ?callStack = thawCallStack ?callStack in handler) +-- | 'interpose' with the effect handler as the last argument.+--+-- @since 2.4.0.0+interposeWith+  :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es)+  => Eff es a+  -> EffectHandler e es+  -- ^ The effect handler.+  -> Eff es a+interposeWith m handler = interpose handler m+ -- | Replace the handler of an existing effect with a new one that uses other, -- private effects. -- -- @'interpose' ≡ 'impose' 'id'@ impose-  :: forall e es handlerEs a b. (DispatchOf e ~ Dynamic, e :> es)+  :: forall e es handlerEs a b. (HasCallStack, DispatchOf e ~ Dynamic, e :> es)   => (Eff handlerEs a -> Eff es b)   -- ^ Introduction of effects encapsulated within the handler.   -> EffectHandler e handlerEs@@ -523,7 +613,128 @@   where     mkHandler es = Handler es (let ?callStack = thawCallStack ?callStack in handler) +-- | 'impose' with the effect handler as the last argument.+--+-- @since 2.4.0.0+imposeWith+  :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es)+  => (Eff handlerEs a -> Eff es b)+  -- ^ Introduction of effects encapsulated within the handler.+  -> Eff es a+  -> EffectHandler e handlerEs+  -- ^ The effect handler.+  -> Eff es b+imposeWith runHandlerEs m handler = impose runHandlerEs handler m+ ----------------------------------------+-- First order effects++-- | Type signature of a first order effect handler.+--+-- @since 2.4.0.0+type EffectHandler_ (e :: Effect) (es :: [Effect])+  = forall a localEs. HasCallStack+  => e (Eff localEs) a+  -- ^ The operation.+  -> Eff es a++-- | 'interpret' for first order effects.+--+-- @since 2.4.0.0+interpret_+  :: (HasCallStack, DispatchOf e ~ Dynamic)+  => EffectHandler_ e es+  -- ^ The effect handler.+  -> Eff (e : es) a+  -> Eff      es  a+interpret_ handler = interpret (const handler)++-- | 'interpretWith' for first order effects.+--+-- @since 2.4.0.0+interpretWith_+  :: (HasCallStack, DispatchOf e ~ Dynamic)+  => Eff (e : es) a+  -> EffectHandler_ e es+  -- ^ The effect handler.+  -> Eff      es  a+interpretWith_ m handler = interpret (const handler) m++-- | 'reinterpret' for first order effects.+--+-- @since 2.4.0.0+reinterpret_+  :: (HasCallStack, DispatchOf e ~ Dynamic)+  => (Eff handlerEs a -> Eff es b)+  -- ^ Introduction of effects encapsulated within the handler.+  -> EffectHandler_ e handlerEs+  -- ^ The effect handler.+  -> Eff (e : es) a+  -> Eff      es  b+reinterpret_ runHandlerEs handler = reinterpret runHandlerEs (const handler)++-- | 'reinterpretWith' for first order effects.+--+-- @since 2.4.0.0+reinterpretWith_+  :: (HasCallStack, DispatchOf e ~ Dynamic)+  => (Eff handlerEs a -> Eff es b)+  -- ^ Introduction of effects encapsulated within the handler.+  -> Eff (e : es) a+  -> EffectHandler_ e handlerEs+  -- ^ The effect handler.+  -> Eff      es  b+reinterpretWith_ runHandlerEs m handler = reinterpret runHandlerEs (const handler) m++-- | 'interpose' for first order effects.+--+-- @since 2.4.0.0+interpose_+  :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es)+  => EffectHandler_ e es+  -- ^ The effect handler.+  -> Eff es a+  -> Eff es a+interpose_ handler = interpose (const handler)++-- | 'interposeWith' for first order effects.+--+-- @since 2.4.0.0+interposeWith_+  :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es)+  => Eff es a+  -> EffectHandler_ e es+  -- ^ The effect handler.+  -> Eff es a+interposeWith_ m handler = interpose (const handler) m++-- | 'impose' for first order effects.+--+-- @since 2.4.0.0+impose_+  :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es)+  => (Eff handlerEs a -> Eff es b)+  -- ^ Introduction of effects encapsulated within the handler.+  -> EffectHandler_ e handlerEs+  -- ^ The effect handler.+  -> Eff es a+  -> Eff es b+impose_ runHandlerEs handler = impose runHandlerEs (const handler)++-- | 'imposeWith' for first order effects.+--+-- @since 2.4.0.0+imposeWith_+  :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es)+  => (Eff handlerEs a -> Eff es b)+  -- ^ Introduction of effects encapsulated within the handler.+  -> Eff es a+  -> EffectHandler_ e handlerEs+  -- ^ The effect handler.+  -> Eff es b+imposeWith_ runHandlerEs m handler = impose runHandlerEs (const handler) m++---------------------------------------- -- Unlifts  -- | Create a local unlifting function with the 'SeqUnlift' strategy. For the@@ -536,8 +747,10 @@   -- ^ Continuation with the unlifting function in scope.   -> Eff es a localSeqUnlift (LocalEnv les) k = unsafeEff $ \es -> do+  requireMatchingStorages es les   seqUnliftIO les $ \unlift -> do     (`unEff` es) $ k $ unsafeEff_ . unlift+{-# INLINE localSeqUnlift #-}  -- | Create a local unlifting function with the 'SeqUnlift' strategy. For the -- general version see 'localUnliftIO'.@@ -548,7 +761,10 @@   -> ((forall r. Eff localEs r -> IO r) -> IO a)   -- ^ Continuation with the unlifting function in scope.   -> Eff es a-localSeqUnliftIO (LocalEnv les) k = liftIO $ seqUnliftIO les k+localSeqUnliftIO (LocalEnv les) k = unsafeEff $ \es -> do+  requireMatchingStorages es les+  seqUnliftIO les k+{-# INLINE localSeqUnliftIO #-}  -- | Create a local unlifting function with the given strategy. localUnlift@@ -559,13 +775,15 @@   -> ((forall r. Eff localEs r -> Eff es r) -> Eff es a)   -- ^ Continuation with the unlifting function in scope.   -> Eff es a-localUnlift (LocalEnv les) strategy k = case strategy of-  SeqUnlift -> unsafeEff $ \es -> do-    seqUnliftIO les $ \unlift -> do+localUnlift (LocalEnv les) strategy k = unsafeEff $ \es -> do+  requireMatchingStorages es les+  case strategy of+    SeqUnlift -> seqUnliftIO les $ \unlift -> do       (`unEff` es) $ k $ unsafeEff_ . unlift-  ConcUnlift p l -> unsafeEff $ \es -> do-    concUnliftIO les p l $ \unlift -> do+    SeqForkUnlift -> seqForkUnliftIO les $ \unlift -> do       (`unEff` es) $ k $ unsafeEff_ . unlift+    ConcUnlift p l -> concUnliftIO les p l $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift {-# INLINE localUnlift #-}  -- | Create a local unlifting function with the given strategy.@@ -577,9 +795,12 @@   -> ((forall r. Eff localEs r -> IO r) -> IO a)   -- ^ Continuation with the unlifting function in scope.   -> Eff es a-localUnliftIO (LocalEnv les) strategy k = case strategy of-  SeqUnlift      -> liftIO $ seqUnliftIO les k-  ConcUnlift p l -> liftIO $ concUnliftIO les p l k+localUnliftIO (LocalEnv les) strategy k = unsafeEff $ \es -> do+  requireMatchingStorages es les+  case strategy of+    SeqUnlift -> seqUnliftIO les k+    SeqForkUnlift -> seqForkUnliftIO les k+    ConcUnlift p l -> concUnliftIO les p l k {-# INLINE localUnliftIO #-}  ----------------------------------------@@ -596,11 +817,11 @@   -> ((forall r. Eff es r -> Eff localEs r) -> Eff es a)   -- ^ Continuation with the lifting function in scope.   -> Eff es a-localSeqLift !_ k = unsafeEff $ \es -> do-  -- The LocalEnv parameter is not used, but we need it to constraint the-  -- localEs type variable. It's also strict so that callers don't cheat.+localSeqLift (LocalEnv les) k = unsafeEff $ \es -> do+  requireMatchingStorages es les   seqUnliftIO es $ \unlift -> do     (`unEff` es) $ k $ unsafeEff_ . unlift+{-# INLINE localSeqLift #-}  -- | Create a local lifting function with the given strategy. --@@ -613,15 +834,15 @@   -> ((forall r. Eff es r -> Eff localEs r) -> Eff es a)   -- ^ Continuation with the lifting function in scope.   -> Eff es a-localLift !_ strategy k = case strategy of-  -- The LocalEnv parameter is not used, but we need it to constraint the-  -- localEs type variable. It's also strict so that callers don't cheat.-  SeqUnlift -> unsafeEff $ \es -> do-    seqUnliftIO es $ \unlift -> do+localLift (LocalEnv les) strategy k = unsafeEff $ \es -> do+  requireMatchingStorages es les+  case strategy of+    SeqUnlift -> seqUnliftIO es $ \unlift -> do       (`unEff` es) $ k $ unsafeEff_ . unlift-  ConcUnlift p l -> unsafeEff $ \es -> do-    concUnliftIO es p l $ \unlift -> do+    SeqForkUnlift -> seqForkUnliftIO es $ \unlift -> do       (`unEff` es) $ k $ unsafeEff_ . unlift+    ConcUnlift p l -> concUnliftIO es p l $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift {-# INLINE localLift #-}  -- | Utility for lifting 'Eff' computations of type@@ -641,12 +862,12 @@   -> ((forall a b. (Eff es a -> Eff es b) -> Eff localEs a -> Eff localEs b) -> Eff es r)   -- ^ Continuation with the lifting function in scope.   -> Eff es r-withLiftMap !_ k = unsafeEff $ \es -> do-  -- The LocalEnv parameter is not used, but we need it to constraint the-  -- localEs type variable. It's also strict so that callers don't cheat.+withLiftMap (LocalEnv les) k = unsafeEff $ \es -> do+  requireMatchingStorages es les   (`unEff` es) $ k $ \mapEff m -> unsafeEff $ \localEs -> do     seqUnliftIO localEs $ \unlift -> do       (`unEff` es) . mapEff . unsafeEff_ $ unlift m+{-# INLINE withLiftMap #-}  -- | Utility for lifting 'IO' computations of type --@@ -681,10 +902,11 @@   -> ((forall a b. (IO a -> IO b) -> Eff localEs a -> Eff localEs b) -> Eff es r)   -- ^ Continuation with the lifting function in scope.   -> Eff es r-withLiftMapIO !_ k = k $ \mapIO m -> unsafeEff $ \es -> do-  -- The LocalEnv parameter is not used, but we need it to constraint the-  -- localEs type variable. It's also strict so that callers don't cheat.-  seqUnliftIO es $ \unlift -> mapIO $ unlift m+withLiftMapIO (LocalEnv les) k = unsafeEff $ \es -> do+  requireMatchingStorages es les+  (`unEff` es) $ k $ \mapIO m -> unsafeEff $ \localEs -> do+    seqUnliftIO localEs $ \unlift -> mapIO $ unlift m+{-# INLINE withLiftMapIO #-}  ---------------------------------------- -- Bidirectional lifts@@ -704,13 +926,16 @@   -> ((forall r. Eff es r -> Eff localEs r) -> (forall r. Eff localEs r -> Eff es r) -> Eff es a)   -- ^ Continuation with the lifting and unlifting function in scope.   -> Eff es a-localLiftUnlift (LocalEnv les) strategy k = case strategy of-  SeqUnlift -> unsafeEff $ \es -> do-    seqUnliftIO es $ \unliftEs -> do+localLiftUnlift (LocalEnv les) strategy k = unsafeEff $ \es -> do+  requireMatchingStorages es les+  case strategy of+    SeqUnlift -> seqUnliftIO es $ \unliftEs -> do       seqUnliftIO les $ \unliftLocalEs -> do         (`unEff` es) $ k (unsafeEff_ . unliftEs) (unsafeEff_ . unliftLocalEs)-  ConcUnlift p l -> unsafeEff $ \es -> do-    concUnliftIO es p l $ \unliftEs -> do+    SeqForkUnlift -> seqForkUnliftIO es $ \unliftEs -> do+      seqForkUnliftIO les $ \unliftLocalEs -> do+        (`unEff` es) $ k (unsafeEff_ . unliftEs) (unsafeEff_ . unliftLocalEs)+    ConcUnlift p l -> concUnliftIO es p l $ \unliftEs -> do       concUnliftIO les p l $ \unliftLocalEs -> do         (`unEff` es) $ k (unsafeEff_ . unliftEs) (unsafeEff_ . unliftLocalEs) {-# INLINE localLiftUnlift #-}@@ -731,15 +956,18 @@   -> ((forall r. IO r -> Eff localEs r) -> (forall r. Eff localEs r -> IO r) -> IO a)   -- ^ Continuation with the lifting and unlifting function in scope.   -> Eff es a-localLiftUnliftIO (LocalEnv les) strategy k = case strategy of-  SeqUnlift      -> liftIO $ seqUnliftIO les $ k unsafeEff_-  ConcUnlift p l -> liftIO $ concUnliftIO les p l $ k unsafeEff_+localLiftUnliftIO (LocalEnv les) strategy k = unsafeEff $ \es -> do+  requireMatchingStorages es les+  case strategy of+    SeqUnlift      -> seqUnliftIO les $ k unsafeEff_+    SeqForkUnlift  -> seqForkUnliftIO les $ k unsafeEff_+    ConcUnlift p l -> concUnliftIO les p l $ k unsafeEff_ {-# INLINE localLiftUnliftIO #-}  ---------------------------------------- -- Misc --- | Lend an effect to the local environment.+-- | Lend effects to the local environment. -- -- Consider the following effect: --@@ -777,93 +1005,119 @@ --   runD :: IOE :> es => Eff (D : es) a -> Eff es a --   runD = interpret $ \env -> \case --     D -> localSeqUnlift env $ \unlift -> do---       localSeqLend @IOE env $ \useIOE -> do+--       localSeqLend @'[IOE] env $ \useIOE -> do --         unlift . useIOE . runE $ pure () -- :} ----- @since 2.3.1.0+-- @since 2.4.0.0 localSeqLend-  :: (e :> es, SharedSuffix es handlerEs)+  :: forall lentEs es handlerEs localEs a+   . (HasCallStack, KnownSubset lentEs es, SharedSuffix es handlerEs)   => LocalEnv localEs handlerEs-  -> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)+  -> ((forall r. Eff (lentEs ++ localEs) r -> Eff localEs r) -> Eff es a)   -- ^ Continuation with the lent handler in scope.   -> Eff es a localSeqLend (LocalEnv les) k = unsafeEff $ \es -> do-  eles <- copyRef es les+  eles <- copyRefs @lentEs es les   seqUnliftIO eles $ \unlift -> (`unEff` es) $ k $ unsafeEff_ . unlift+{-# INLINE localSeqLend #-} --- | Lend an effect to the local environment with a given unlifting strategy.+-- | Lend effects to the local environment with a given unlifting strategy. -- -- Generalizes 'localSeqLend'. ----- @since 2.3.1.0+-- @since 2.4.0.0 localLend-  :: (e :> es, SharedSuffix es handlerEs)+  :: forall lentEs es handlerEs localEs a+   . (HasCallStack, KnownSubset lentEs es, SharedSuffix es handlerEs)   => LocalEnv localEs handlerEs   -> UnliftStrategy-  -> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)+  -> ((forall r. Eff (lentEs ++ localEs) r -> Eff localEs r) -> Eff es a)   -- ^ Continuation with the lent handler in scope.   -> Eff es a-localLend (LocalEnv les) strategy k = case strategy of-  SeqUnlift -> unsafeEff $ \es -> do-    eles <- copyRef es les-    seqUnliftIO eles $ \unlift -> (`unEff` es) $ k $ unsafeEff_ . unlift-  ConcUnlift p l -> unsafeEff $ \es -> do-    eles <- copyRef es les-    concUnliftIO eles p l $ \unlift -> (`unEff` es) $ k $ unsafeEff_ . unlift+localLend (LocalEnv les) strategy k = unsafeEff $ \es -> do+  eles <- copyRefs @lentEs es les+  case strategy of+    SeqUnlift -> seqUnliftIO eles $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift+    SeqForkUnlift -> seqForkUnliftIO eles $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift+    ConcUnlift p l -> concUnliftIO eles p l $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift {-# INLINE localLend #-} --- | Borrow an effect from the local environment.+-- | Borrow effects from the local environment. ----- @since 2.3.1.0+-- @since 2.4.0.0 localSeqBorrow-  :: (e :> localEs, SharedSuffix es handlerEs)+  :: forall borrowedEs es handlerEs localEs a+   . (HasCallStack, KnownSubset borrowedEs localEs, SharedSuffix es handlerEs)   => LocalEnv localEs handlerEs-  -> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)+  -> ((forall r. Eff (borrowedEs ++ es) r -> Eff es r) -> Eff es a)   -- ^ Continuation with the borrowed handler in scope.   -> Eff es a localSeqBorrow (LocalEnv les) k = unsafeEff $ \es -> do-  ees <- copyRef les es+  ees <- copyRefs @borrowedEs les es   seqUnliftIO ees $ \unlift -> (`unEff` es) $ k $ unsafeEff_ . unlift+{-# INLINE localSeqBorrow #-} --- | Borrow an effect from the local environment with a given unlifting+-- | Borrow effects from the local environment with a given unlifting -- strategy. -- -- Generalizes 'localSeqBorrow'. ----- @since 2.3.1.0+-- @since 2.4.0.0 localBorrow-  :: (e :> localEs, SharedSuffix es handlerEs)+  :: forall borrowedEs es handlerEs localEs a+   . (HasCallStack, KnownSubset borrowedEs localEs, SharedSuffix es handlerEs)   => LocalEnv localEs handlerEs   -> UnliftStrategy-  -> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)+  -> ((forall r. Eff (borrowedEs ++ es) r -> Eff es r) -> Eff es a)   -- ^ Continuation with the borrowed handler in scope.   -> Eff es a-localBorrow (LocalEnv les) strategy k = case strategy of-  SeqUnlift -> unsafeEff $ \es -> do-    ees <- copyRef les es-    seqUnliftIO ees $ \unlift -> (`unEff` es) $ k $ unsafeEff_ . unlift-  ConcUnlift p l -> unsafeEff $ \es -> do-    ees <- copyRef les es-    concUnliftIO ees p l $ \unlift -> (`unEff` es) $ k $ unsafeEff_ . unlift+localBorrow (LocalEnv les) strategy k = unsafeEff $ \es -> do+  ees <- copyRefs @borrowedEs les es+  case strategy of+    SeqUnlift -> seqUnliftIO ees $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift+    SeqForkUnlift -> seqForkUnliftIO ees $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift+    ConcUnlift p l -> concUnliftIO ees p l $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift {-# INLINE localBorrow #-} -copyRef-  :: forall e srcEs destEs. e :> srcEs+copyRefs+  :: forall es srcEs destEs+   . (HasCallStack, KnownSubset es srcEs)   => Env srcEs   -> Env destEs-  -> IO (Env (e : destEs))-copyRef (Env hoffset hrefs hstorage) (Env offset refs0 storage) = do-  when (hstorage /= storage) $ do-    error "storages do not match"-  let size = sizeofPrimArray refs0 - offset-      i = 2 * reifyIndex @e @srcEs-  mrefs <- newPrimArray (size + 2)-  copyPrimArray mrefs 0 hrefs (hoffset + i) 2-  copyPrimArray mrefs 2 refs0 offset size+  -> IO (Env (es ++ destEs))+copyRefs src@(Env soffset srefs _) dest@(Env doffset drefs storage) = do+  requireMatchingStorages src dest+  let es = reifyIndices @es @srcEs+      esSize = length es+      destSize = sizeofPrimArray drefs - doffset+  mrefs <- newPrimArray (esSize + destSize)+  copyPrimArray mrefs esSize drefs doffset destSize+  let writeRefs i = \case+        [] -> pure ()+        (x : xs) -> do+          writePrimArray mrefs i $ indexPrimArray srefs (soffset + x)+          writeRefs (i + 1) xs+  writeRefs 0 es   refs <- unsafeFreezePrimArray mrefs   pure $ Env 0 refs storage+{-# NOINLINE copyRefs #-} +requireMatchingStorages :: HasCallStack => Env es1 -> Env es2 -> IO ()+requireMatchingStorages es1 es2+  | envStorage es1 /= envStorage es2 = error+    $ "Env and LocalEnv point to different Storages.\n"+    ++ "If you passed LocalEnv to a different thread and tried to create an "+    ++ "unlifting function there, it's not allowed. You need to create it in "+    ++ "the thread of the effect handler."+  | otherwise = pure ()+ -- | Require that both effect stacks share an opaque suffix. -- -- Functions from the 'localUnlift' family utilize this constraint to guarantee@@ -937,4 +1191,5 @@  -- $setup -- >>> import Control.Concurrent (ThreadId, forkIOWithUnmask)+-- >>> import Control.Monad.IO.Class -- >>> import Effectful.Reader.Static
src/Effectful/Error/Dynamic.hs view
@@ -14,7 +14,9 @@   , runErrorNoCallStackWith      -- ** Operations+  , throwErrorWith   , throwError+  , throwError_   , catchError   , handleError   , tryError@@ -34,17 +36,19 @@  -- | Provide the ability to handle errors of type @e@. data Error e :: Effect where-  ThrowError :: e -> Error e m a+  -- | @since 2.4.0.0+  ThrowErrorWith :: (e -> String) -> e -> Error e m a   CatchError :: m a -> (E.CallStack -> e -> m a) -> Error e m a  type instance DispatchOf (Error e) = Dynamic  -- | Handle errors of type @e@ (via "Effectful.Error.Static"). runError-  :: Eff (Error e : es) a+  :: HasCallStack+  => Eff (Error e : es) a   -> Eff es (Either (E.CallStack, e) a) runError = reinterpret E.runError $ \env -> \case-  ThrowError e   -> E.throwError e+  ThrowErrorWith display e -> E.throwErrorWith display e   CatchError m h -> localSeqUnlift env $ \unlift -> do     E.catchError (unlift m) (\cs -> unlift . h cs) @@ -53,7 +57,8 @@ -- -- @since 2.3.0.0 runErrorWith-  :: (E.CallStack -> e -> Eff es a)+  :: HasCallStack+  => (E.CallStack -> e -> Eff es a)   -- ^ The error handler.   -> Eff (Error e : es) a   -> Eff es a@@ -66,14 +71,16 @@ -- -- @since 2.3.0.0 runErrorNoCallStack-  :: Eff (Error e : es) a+  :: HasCallStack+  => Eff (Error e : es) a   -> Eff es (Either e a) runErrorNoCallStack = fmap (either (Left . snd) Right) . runError  -- | Handle errors of type @e@ (via "Effectful.Error.Static") with a specific -- error handler. In case of an error discard the 'CallStack'. runErrorNoCallStackWith-  :: (e -> Eff es a)+  :: HasCallStack+  => (e -> Eff es a)   -- ^ The error handler.   -> Eff (Error e : es) a   -> Eff es a@@ -81,13 +88,36 @@   Left e -> handler e   Right a -> pure a --- | Throw an error of type @e@.+-- | Throw an error of type @e@ and specify a display function in case a+-- third-party code catches the internal exception and 'show's it.+--+-- @since 2.4.0.0+throwErrorWith+  :: (HasCallStack, Error e :> es)+  => (e -> String)+  -- ^ The display function.+  -> e+  -- ^ The error.+  -> Eff es a+throwErrorWith display = withFrozenCallStack send . ThrowErrorWith display++-- | Throw an error of type @e@ with 'show' as a display function. throwError+  :: (HasCallStack, Error e :> es, Show e)+  => e+  -- ^ The error.+  -> Eff es a+throwError = withFrozenCallStack throwErrorWith show++-- | Throw an error of type @e@ with no display function.+--+-- @since 2.4.0.0+throwError_   :: (HasCallStack, Error e :> es)   => e   -- ^ The error.   -> Eff es a-throwError e = withFrozenCallStack $ send (ThrowError e)+throwError_ = withFrozenCallStack throwErrorWith (const "<opaque>")  -- | Handle an error of type @e@. catchError@@ -102,7 +132,7 @@ -- | The same as @'flip' 'catchError'@, which is useful in situations where the -- code for the handler is shorter. handleError-  :: Error e :> es+  :: (HasCallStack, Error e :> es)   => (E.CallStack -> e -> Eff es a)   -- ^ A handler for errors in the inner computation.   -> Eff es a
src/Effectful/Error/Static.hs view
@@ -1,13 +1,13 @@ -- | Support for handling errors of a particular type, i.e. checked exceptions. -- -- The 'Error' effect is __not__ a general mechanism for handling regular--- exceptions, that's what functions from the @exceptions@ library are for (see--- "Control.Monad.Catch" for more information).+-- exceptions, that's what functions from the "Effectful.Exception" module are+-- for. -- -- In particular, regular exceptions of type @e@ are distinct from errors of -- type @e@ and will __not__ be caught by functions from this module: ----- >>> import qualified Control.Monad.Catch as E+-- >>> import Effectful.Exception qualified as E -- -- >>> boom = error "BOOM!" --@@ -16,14 +16,14 @@ -- ... -- -- If you want to catch regular exceptions, you should use--- 'Control.Monad.Catch.catch' (or a similar function):+-- 'Effectful.Exception.catch' (or a similar function): -- -- >>> runEff $ boom `E.catch` \(_::ErrorCall) -> pure "caught" -- "caught" -- -- On the other hand, functions for safe finalization and management of--- resources such as 'Control.Monad.Catch.finally' and--- 'Control.Monad.Catch.bracket' work as expected:+-- resources such as 'Effectful.Exception.finally' and+-- 'Effectful.Exception.bracket' work as expected: -- -- >>> msg = liftIO . putStrLn --@@ -43,8 +43,8 @@ -- effect with regard to other stateful effects does not matter. Consider the -- following: ----- >>> import qualified Control.Monad.State.Strict as T--- >>> import qualified Control.Monad.Except as T+-- >>> import Control.Monad.State.Strict qualified as T+-- >>> import Control.Monad.Except qualified as T -- -- >>> m1 = (T.modify (++ " there!") >> T.throwError "oops") `T.catchError` \_ -> pure () --@@ -74,7 +74,7 @@ -- -- /Hint:/ if you'd like to reproduce the transactional behavior with the -- t'Effectful.State.Static.Local.State' effect, appropriate usage of--- 'Control.Monad.Catch.bracketOnError' will do the trick.+-- 'Effectful.Exception.bracketOnError' will do the trick. module Effectful.Error.Static   ( -- * Effect     Error@@ -86,7 +86,9 @@   , runErrorNoCallStackWith      -- ** Operations+  , throwErrorWith   , throwError+  , throwError_   , catchError   , handleError   , tryError@@ -99,6 +101,7 @@   ) where  import Control.Exception+import Data.Kind import GHC.Stack  import Effectful@@ -107,7 +110,7 @@ import Effectful.Internal.Utils  -- | Provide the ability to handle errors of type @e@.-data Error e :: Effect+data Error (e :: Type) :: Effect  type instance DispatchOf (Error e) = Static NoSideEffects newtype instance StaticRep (Error e) = Error ErrorId@@ -115,7 +118,8 @@ -- | Handle errors of type @e@. runError   :: forall e es a-  .  Eff (Error e : es) a+   . HasCallStack+  => Eff (Error e : es) a   -> Eff es (Either (CallStack, e) a) runError m = unsafeEff $ \es0 -> mask $ \unmask -> do   eid <- newErrorId@@ -133,7 +137,8 @@ -- -- @since 2.3.0.0 runErrorWith-  :: (CallStack -> e -> Eff es a)+  :: HasCallStack+  => (CallStack -> e -> Eff es a)   -- ^ The error handler.   -> Eff (Error e : es) a   -> Eff es a@@ -146,14 +151,16 @@ -- @since 2.3.0.0 runErrorNoCallStack   :: forall e es a-  .  Eff (Error e : es) a+   . HasCallStack+  => Eff (Error e : es) a   -> Eff es (Either e a) runErrorNoCallStack = fmap (either (Left . snd) Right) . runError  -- | Handle errors of type @e@ with a specific error handler. In case of an -- error discard the 'CallStack'. runErrorNoCallStackWith-  :: (e -> Eff es a)+  :: HasCallStack+  => (e -> Eff es a)   -- ^ The error handler.   -> Eff (Error e : es) a   -> Eff es a@@ -161,19 +168,42 @@   Left e -> handler e   Right a -> pure a --- | Throw an error of type @e@.+-- | Throw an error of type @e@ and specify a display function in case a+-- third-party code catches the internal exception and 'show's it.+--+-- @since 2.4.0.0+throwErrorWith+  :: forall e es a. (HasCallStack, Error e :> es)+  => (e -> String)+  -- ^ The display function.+  -> e+  -- ^ The error.+  -> Eff es a+throwErrorWith display e = unsafeEff $ \es -> do+  Error eid <- getEnv @(Error e) es+  throwIO $ ErrorWrapper eid callStack (display e) (toAny e)++-- | Throw an error of type @e@ with 'show' as a display function. throwError+  :: forall e es a. (HasCallStack, Error e :> es, Show e)+  => e+  -- ^ The error.+  -> Eff es a+throwError = withFrozenCallStack throwErrorWith show++-- | Throw an error of type @e@ with no display function.+--+-- @since 2.4.0.0+throwError_   :: forall e es a. (HasCallStack, Error e :> es)   => e   -- ^ The error.   -> Eff es a-throwError e = unsafeEff $ \es -> do-  Error eid <- getEnv @(Error e) es-  throwIO $ ErrorWrapper eid callStack (toAny e)+throwError_ = withFrozenCallStack throwErrorWith (const "<opaque>")  -- | Handle an error of type @e@. catchError-  :: forall e es a. Error e :> es+  :: forall e es a. (HasCallStack, Error e :> es)   => Eff es a   -- ^ The inner computation.   -> (CallStack -> e -> Eff es a)@@ -187,7 +217,7 @@ -- | The same as @'flip' 'catchError'@, which is useful in situations where the -- code for the handler is shorter. handleError-  :: forall e es a. Error e :> es+  :: forall e es a. (HasCallStack, Error e :> es)   => (CallStack -> e -> Eff es a)   -- ^ A handler for errors in the inner computation.   -> Eff es a@@ -198,7 +228,7 @@ -- | Similar to 'catchError', but returns an 'Either' result which is a 'Right' -- if no error was thrown and a 'Left' otherwise. tryError-  :: forall e es a. Error e :> es+  :: forall e es a. (HasCallStack, Error e :> es)   => Eff es a   -- ^ The inner computation.   -> Eff es (Either (CallStack, e) a)@@ -208,7 +238,7 @@ -- Helpers  newtype ErrorId = ErrorId Unique-  deriving Eq+  deriving newtype Eq  -- | A unique is picked so that distinct 'Error' handlers for the same type -- don't catch each other's exceptions.@@ -222,21 +252,25 @@   -> IO r   -> IO r tryHandler ex eid0 handler next = case fromException ex of-  Just (ErrorWrapper eid cs e)+  Just (ErrorWrapper eid cs _ e)     | eid0 == eid -> pure $ handler cs (fromAny e)     | otherwise   -> next   Nothing -> next -data ErrorWrapper = ErrorWrapper !ErrorId CallStack Any+data ErrorWrapper = ErrorWrapper !ErrorId CallStack String Any+ instance Show ErrorWrapper where-  showsPrec p (ErrorWrapper _ cs _)-    = ("Effectful.Error.Static.ErrorWrapper\n\n" ++)-    . showsPrec p (prettyCallStack cs)+  showsPrec _ (ErrorWrapper _ cs errRep _)+    = ("Effectful.Error.Static.ErrorWrapper: " ++)+    . (errRep ++)+    . ("\n" ++)+    . (prettyCallStack cs ++)+ instance Exception ErrorWrapper  catchErrorIO :: ErrorId -> IO a -> (CallStack -> e -> IO a) -> IO a catchErrorIO eid m handler = do-  m `catch` \err@(ErrorWrapper etag cs e) -> do+  m `catch` \err@(ErrorWrapper etag cs _ e) -> do     if eid == etag       then handler cs (fromAny e)       else throwIO err
+ src/Effectful/Exception.hs view
@@ -0,0 +1,130 @@+-- | The 'Eff' monad comes with instances of 'MonadThrow', 'MonadCatch' and+-- 'MonadMask' from the+-- [@exceptions@](https://hackage.haskell.org/package/exceptions) library, so+-- this module simply re-exports the interface of the+-- [@safe-exceptions@](https://hackage.haskell.org/package/safe-exceptions)+-- library.+--+-- Why @safe-exceptions@ and not @exceptions@? Because the former makes it much+-- easier to correctly deal with asynchronous exceptions (for more information+-- see its [README](https://github.com/fpco/safe-exceptions#readme)) and+-- provides more convenience functions.+module Effectful.Exception+  ( -- * Throwing+    C.MonadThrow(..)+  , Safe.throwString+  , Safe.StringException(..)++    -- * Catching (with recovery)+  , C.MonadCatch(..)+  , Safe.catchIO+  , Safe.catchIOError+  , Safe.catchAny+  , Safe.catchDeep+  , Safe.catchAnyDeep+  , Safe.catchAsync+  , Safe.catchJust++  , Safe.handle+  , Safe.handleIO+  , Safe.handleIOError+  , Safe.handleAny+  , Safe.handleDeep+  , Safe.handleAnyDeep+  , Safe.handleAsync+  , Safe.handleJust++  , Safe.try+  , Safe.tryIO+  , Safe.tryAny+  , Safe.tryDeep+  , Safe.tryAnyDeep+  , Safe.tryAsync+  , Safe.tryJust++  , Safe.Handler(..)+  , Safe.catches+  , Safe.catchesDeep+  , Safe.catchesAsync++    -- * Cleanup (no recovery)+  , C.MonadMask(..)+  , C.ExitCase(..)+  , Safe.onException+  , Safe.bracket+  , Safe.bracket_+  , Safe.finally+  , Safe.withException+  , Safe.bracketOnError+  , Safe.bracketOnError_+  , Safe.bracketWithError++    -- * Utilities++    -- ** Coercion to sync and async+  , Safe.SyncExceptionWrapper(..)+  , Safe.toSyncException+  , Safe.AsyncExceptionWrapper(..)+  , Safe.toAsyncException++    -- ** Check exception type+  , Safe.isSyncException+  , Safe.isAsyncException++    -- ** Evaluation+  , evaluate+  , evaluateDeep++    -- * Re-exports from "Control.Exception"++    -- ** The 'SomeException' type+  , E.SomeException(..)++    -- ** The 'Exception' class+  , E.Exception(..)++    -- ** Concrete exception types+  , E.IOException+  , E.ArithException(..)+  , E.ArrayException(..)+  , E.AssertionFailed(..)+  , E.NoMethodError(..)+  , E.PatternMatchFail(..)+  , E.RecConError(..)+  , E.RecSelError(..)+  , E.RecUpdError(..)+  , E.ErrorCall(..)+  , E.TypeError(..)++    -- ** Asynchronous exceptions+  , E.SomeAsyncException(..)+  , E.AsyncException(..)+  , E.asyncExceptionToException+  , E.asyncExceptionFromException+  , E.NonTermination(..)+  , E.NestedAtomically(..)+  , E.BlockedIndefinitelyOnMVar(..)+  , E.BlockedIndefinitelyOnSTM(..)+  , E.AllocationLimitExceeded(..)+  , E.CompactionFailed(..)+  , E.Deadlock(..)++    -- ** Assertions+  , E.assert+  ) where++import Control.DeepSeq+import Control.Exception qualified as E+import Control.Exception.Safe qualified as Safe+import Control.Monad.Catch qualified as C++import Effectful+import Effectful.Dispatch.Static++-- | Lifted version of 'E.evaluate'.+evaluate :: a -> Eff es a+evaluate = unsafeEff_ . E.evaluate++-- | Deeply evaluate a value using 'evaluate' and 'NFData'.+evaluateDeep :: NFData a => a -> Eff es a+evaluateDeep = unsafeEff_ . E.evaluate . force
src/Effectful/Fail.hs view
@@ -14,11 +14,11 @@ import Effectful.Internal.Monad (Fail(..))  -- | Run the 'Fail' effect via 'Error'.-runFail :: Eff (Fail : es) a -> Eff es (Either String a)-runFail = reinterpret runErrorNoCallStack $ \_ -> \case+runFail :: HasCallStack => Eff (Fail : es) a -> Eff es (Either String a)+runFail = reinterpret_ runErrorNoCallStack $ \case   Fail msg -> throwError msg  -- | Run the 'Fail' effect via the 'MonadFail' instance for 'IO'.-runFailIO :: IOE :> es => Eff (Fail : es) a -> Eff es a-runFailIO = interpret $ \_ -> \case+runFailIO :: (HasCallStack, IOE :> es) => Eff (Fail : es) a -> Eff es a+runFailIO = interpret_ $ \case   Fail msg -> liftIO $ fail msg
src/Effectful/Internal/Effect.hs view
@@ -10,6 +10,7 @@   , (:>)(..)   , (:>>)   , Subset(..)+  , KnownSubset   , KnownPrefix(..)   , IsUnknownSuffixOf   , type (++)@@ -70,8 +71,8 @@  ---------------------------------------- --- | Provide evidence that @xs@ is a subset of @es@.-class KnownPrefix es => Subset (xs :: [Effect]) (es :: [Effect]) where+-- | Provide evidence that @subEs@ is a subset of @es@.+class KnownPrefix es => Subset (subEs :: [Effect]) (es :: [Effect]) where   subsetFullyKnown :: Bool   subsetFullyKnown =     -- Don't show "minimal complete definition" in haddock.@@ -86,8 +87,8 @@ -- have the same unknown suffix. instance {-# INCOHERENT #-}   ( KnownPrefix es-  , xs `IsUnknownSuffixOf` es-  ) => Subset xs es where+  , subEs `IsUnknownSuffixOf` es+  ) => Subset subEs es where   subsetFullyKnown = False   reifyIndices = [] @@ -96,12 +97,19 @@   subsetFullyKnown = True   reifyIndices = [] -instance (e :> es, Subset xs es) => Subset (e : xs) es where-  subsetFullyKnown = subsetFullyKnown @xs @es-  reifyIndices = reifyIndex @e @es : reifyIndices @xs @es+instance (e :> es, Subset subEs es) => Subset (e : subEs) es where+  subsetFullyKnown = subsetFullyKnown @subEs @es+  reifyIndices = reifyIndex @e @es : reifyIndices @subEs @es  ---- +-- | Provide evidence that @subEs@ is a known subset of @es@.+class Subset subEs es => KnownSubset (subEs :: [Effect]) (es :: [Effect])+instance KnownSubset '[] es+instance (e :> es, KnownSubset subEs es) => KnownSubset (e : subEs) es++----+ -- | Calculate length of a statically known prefix of @es@. class KnownPrefix (es :: [Effect]) where   prefixLength :: Int@@ -114,10 +122,10 @@  ---- --- | Require that @xs@ is the unknown suffix of @es@.-class (xs :: [Effect]) `IsUnknownSuffixOf` (es :: [Effect])-instance {-# INCOHERENT #-} xs ~ es => xs `IsUnknownSuffixOf` es-instance xs `IsUnknownSuffixOf` es => xs `IsUnknownSuffixOf` (e : es)+-- | Require that @subEs@ is the unknown suffix of @es@.+class (subEs :: [Effect]) `IsUnknownSuffixOf` (es :: [Effect])+instance {-# INCOHERENT #-} subEs ~ es => subEs `IsUnknownSuffixOf` es+instance subEs `IsUnknownSuffixOf` es => subEs `IsUnknownSuffixOf` (e : es)  ---- 
src/Effectful/Internal/Env.hs view
@@ -1,10 +1,20 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} module Effectful.Internal.Env   ( -- * The environment     Env(..)+  , Ref(..)+  , Version   , Storage(..)+  , AnyEffect+  , toAnyEffect+  , fromAnyEffect+  , AnyRelinker+  , toAnyRelinker+  , fromAnyRelinker      -- ** Relinker   , Relinker(..)@@ -40,9 +50,12 @@  import Control.Monad import Control.Monad.Primitive+import Data.IORef.Strict import Data.Primitive.PrimArray import Data.Primitive.SmallArray-import GHC.Stack (HasCallStack)+import Data.Primitive.Types+import GHC.Exts ((*#), (+#))+import GHC.Stack  import Effectful.Internal.Effect import Effectful.Internal.Utils@@ -74,19 +87,78 @@ -- data Env (es :: [Effect]) = Env   { envOffset  :: !Int-  , envRefs    :: !(PrimArray Int)+  , envRefs    :: !(PrimArray Ref)   , envStorage :: !(IORef' Storage)   } +-- | Reference to the effect in 'Storage'.+data Ref = Ref !Int !Version++instance Prim Ref where+  sizeOf# _ = 2# *# sizeOf# (undefined :: Int)+  alignment# _ = alignment# (undefined :: Int)+  indexByteArray# arr i =+    let n = 2# *# i+        ref = indexByteArray# arr n+        version = indexByteArray# arr (n +# 1#)+    in Ref ref version+  readByteArray# arr i s0 =+    let n = 2# *# i+        !(# s1, ref #) = readByteArray# arr n s0+        !(# s2, version #) = readByteArray# arr (n +# 1#) s1+    in (# s2, Ref ref version #)+  writeByteArray# arr i (Ref ref version) s0 =+    let n = 2# *# i+        s1 = writeByteArray# arr n ref s0+        s2 = writeByteArray# arr (n +# 1#) version s1+    in s2+  indexOffAddr# addr i =+    let n = 2# *# i+        ref = indexOffAddr# addr n+        version = indexOffAddr# addr (n +# 1#)+    in Ref ref version+  readOffAddr# addr i s0 =+    let n = 2# *# i+        !(# s1, ref #) = readOffAddr# addr n s0+        !(# s2, version #) = readOffAddr# addr (n +# 1#) s1+    in (# s2, Ref ref version #)+  writeOffAddr# addr i (Ref ref version) s0 =+    let n = 2# *# i+        s1 = writeOffAddr# addr n ref s0+        s2 = writeOffAddr# addr (n +# 1#) version s1+    in s2++-- | Version of the effect.+newtype Version = Version Int+  deriving newtype (Eq, Ord, Prim, Show)+ -- | A storage of effects. data Storage = Storage   { stSize      :: !Int-  , stVersion   :: !Int-  , stVersions  :: !(MutablePrimArray RealWorld Int)-  , stEffects   :: !(SmallMutableArray RealWorld Any)-  , stRelinkers :: !(SmallMutableArray RealWorld Any)+  , stVersion   :: !Version+  , stVersions  :: !(MutablePrimArray RealWorld Version)+  , stEffects   :: !(SmallMutableArray RealWorld AnyEffect)+  , stRelinkers :: !(SmallMutableArray RealWorld AnyRelinker)   } +-- | Effect in 'Storage'.+newtype AnyEffect = AnyEffect Any++toAnyEffect :: EffectRep (DispatchOf e) e -> AnyEffect+toAnyEffect = AnyEffect . toAny++fromAnyEffect :: AnyEffect -> EffectRep (DispatchOf e) e+fromAnyEffect (AnyEffect e) = fromAny e++-- | Relinker in 'Storage'.+newtype AnyRelinker = AnyRelinker Any++toAnyRelinker :: Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker+toAnyRelinker = AnyRelinker . toAny++fromAnyRelinker :: AnyRelinker -> Relinker (EffectRep (DispatchOf e)) e+fromAnyRelinker (AnyRelinker f) = fromAny f+ ---------------------------------------- -- Relinker @@ -94,7 +166,7 @@ -- a deep copy of the representation of the effect when cloning the environment. newtype Relinker :: (Effect -> Type) -> Effect -> Type where   Relinker-    :: ((forall es. Env es -> IO (Env es)) -> rep e -> IO (rep e))+    :: (HasCallStack => (forall es. Env es -> IO (Env es)) -> rep e -> IO (rep e))     -> Relinker rep e  -- | A dummy 'Relinker'.@@ -125,13 +197,13 @@ -- Operations  -- | Create an empty environment.-emptyEnv :: IO (Env '[])+emptyEnv :: HasCallStack => IO (Env '[]) emptyEnv = Env 0   <$> (unsafeFreezePrimArray =<< newPrimArray 0)   <*> (newIORef' =<< emptyStorage)  -- | Clone the environment to use it in a different thread.-cloneEnv :: Env es -> IO (Env es)+cloneEnv :: HasCallStack => Env es -> IO (Env es) cloneEnv (Env offset refs storage0) = do   Storage storageSize version vs0 es0 fs0 <- readIORef' storage0   vsSize <- getSizeofMutablePrimArray  vs0@@ -149,10 +221,10 @@         0 -> pure ()         k -> do           let i = k - 1-          Relinker f <- fromAny <$> readSmallArray fs i+          Relinker relinker <- fromAnyRelinker <$> readSmallArray fs i           readSmallArray es i-            >>= f (relinkEnv storage) . fromAny-            >>= writeSmallArray' es i . toAny+            >>= relinker (relinkEnv storage) . fromAnyEffect+            >>= writeSmallArray' es i . toAnyEffect           relinkEffects i   relinkEffects storageSize   pure $ Env offset refs storage@@ -162,7 +234,8 @@ -- -- @since 2.2.0.0 restoreEnv-  :: Env es -- ^ Destination.+  :: HasCallStack+  => Env es -- ^ Destination.   -> Env es -- ^ Source.   -> IO () restoreEnv dest src = do@@ -183,30 +256,30 @@ -- | Get the current size of the environment. sizeEnv :: Env es -> IO Int sizeEnv (Env offset refs _) = do-  pure $ (sizeofPrimArray refs - offset) `div` 2+  pure $ sizeofPrimArray refs - offset  -- | Access the tail of the environment. tailEnv :: Env (e : es) -> IO (Env es) tailEnv (Env offset refs storage) = do-  pure $ Env (offset + 2) refs storage+  pure $ Env (offset + 1) refs storage  ---------------------------------------- -- Extending and shrinking  -- | Extend the environment with a new data type. consEnv-  :: EffectRep (DispatchOf e) e+  :: HasCallStack+  => EffectRep (DispatchOf e) e   -- ^ The representation of the effect.   -> Relinker (EffectRep (DispatchOf e)) e   -> Env es   -> IO (Env (e : es)) consEnv e f (Env offset refs0 storage) = do   let size = sizeofPrimArray refs0 - offset-  mrefs <- newPrimArray (size + 2)-  copyPrimArray mrefs 2 refs0 offset size-  (ref, version) <- insertEffect storage e f+  mrefs <- newPrimArray (size + 1)+  copyPrimArray mrefs 1 refs0 offset size+  ref <- insertEffect storage e f   writePrimArray mrefs 0 ref-  writePrimArray mrefs 1 version   refs <- unsafeFreezePrimArray mrefs   pure $ Env 0 refs storage {-# NOINLINE consEnv #-}@@ -215,7 +288,7 @@ -- -- /Note:/ after calling this function @e@ from the input environment is no -- longer usable.-unconsEnv :: Env (e : es) -> IO ()+unconsEnv :: HasCallStack => Env (e : es) -> IO () unconsEnv (Env _ refs storage) = do   deleteEffect storage (indexPrimArray refs 0) {-# NOINLINE unconsEnv #-}@@ -227,7 +300,7 @@ -- /Note:/ unlike in 'putEnv' the value in not changed in place, so only the new -- environment will see it. replaceEnv-  :: forall e es. e :> es+  :: forall e es. (HasCallStack, e :> es)   => EffectRep (DispatchOf e) e   -- ^ The representation of the effect.   -> Relinker (EffectRep (DispatchOf e)) e@@ -237,10 +310,8 @@   let size = sizeofPrimArray refs0 - offset   mrefs <- newPrimArray size   copyPrimArray mrefs 0 refs0 offset size-  (ref, version) <- insertEffect storage e f-  let i = 2 * reifyIndex @e @es-  writePrimArray mrefs  i      ref-  writePrimArray mrefs (i + 1) version+  ref <- insertEffect storage e f+  writePrimArray mrefs (reifyIndex @e @es) ref   refs <- unsafeFreezePrimArray mrefs   pure $ Env 0 refs storage {-# NOINLINE replaceEnv #-}@@ -249,9 +320,9 @@ -- -- /Note:/ after calling this function the input environment is no longer -- usable.-unreplaceEnv :: forall e es. e :> es => Env es -> IO ()+unreplaceEnv :: forall e es. (HasCallStack, e :> es) => Env es -> IO () unreplaceEnv (Env offset refs storage) = do-  deleteEffect storage $ indexPrimArray refs (offset + 2 * reifyIndex @e @es)+  deleteEffect storage $ indexPrimArray refs (offset + reifyIndex @e @es) {-# NOINLINE unreplaceEnv #-}  ----------------------------------------@@ -260,11 +331,9 @@ subsumeEnv :: forall e es. e :> es => Env es -> IO (Env (e : es)) subsumeEnv (Env offset refs0 storage) = do   let size = sizeofPrimArray refs0 - offset-  mrefs <- newPrimArray (size + 2)-  copyPrimArray mrefs 2 refs0 offset size-  let ix = offset + 2 * reifyIndex @e @es-  writePrimArray mrefs 0 $ indexPrimArray refs0  ix-  writePrimArray mrefs 1 $ indexPrimArray refs0 (ix + 1)+  mrefs <- newPrimArray (size + 1)+  copyPrimArray mrefs 1 refs0 offset size+  writePrimArray mrefs 0 $ indexPrimArray refs0 (offset + reifyIndex @e @es)   refs <- unsafeFreezePrimArray mrefs   pure $ Env 0 refs storage {-# NOINLINE subsumeEnv #-}@@ -273,24 +342,22 @@  -- | Construct an environment containing a permutation (with possible -- duplicates) of a subset of effects from the input environment.-injectEnv :: forall xs es. Subset xs es => Env es -> IO (Env xs)+injectEnv :: forall subEs es. Subset subEs es => Env es -> IO (Env subEs) injectEnv (Env offset refs0 storage) = do-  let xs         = reifyIndices @xs @es-      permSize   = 2 * length xs-      prefixSize = 2 * prefixLength @es-      suffixSize = if subsetFullyKnown @xs @es+  let subEs      = reifyIndices @subEs @es+      subEsSize  = length subEs+      prefixSize = prefixLength @es+      suffixSize = if subsetFullyKnown @subEs @es                    then 0                    else sizeofPrimArray refs0 - offset - prefixSize-  mrefs <- newPrimArray (permSize + suffixSize)-  copyPrimArray mrefs permSize refs0 (offset + prefixSize) suffixSize-  let writePermRefs i = \case+  mrefs <- newPrimArray (subEsSize + suffixSize)+  copyPrimArray mrefs subEsSize refs0 (offset + prefixSize) suffixSize+  let writeRefs i = \case         []       -> pure ()-        (e : es) -> do-          let ix = offset + 2 * e-          writePrimArray mrefs  i      $ indexPrimArray refs0  ix-          writePrimArray mrefs (i + 1) $ indexPrimArray refs0 (ix + 1)-          writePermRefs (i + 2) es-  writePermRefs 0 xs+        (x : xs) -> do+          writePrimArray mrefs i $ indexPrimArray refs0 (offset + x)+          writeRefs (i + 1) xs+  writeRefs 0 subEs   refs <- unsafeFreezePrimArray mrefs   pure $ Env 0 refs storage {-# NOINLINE injectEnv #-}@@ -300,55 +367,52 @@  -- | Extract a specific data type from the environment. getEnv-  :: forall e es. e :> es+  :: forall e es. (HasCallStack, e :> es)   => Env es -- ^ The environment.   -> IO (EffectRep (DispatchOf e) e) getEnv env = do   (i, es) <- getLocation @e env-  fromAny <$> readSmallArray es i+  fromAnyEffect <$> readSmallArray es i  -- | Replace the data type in the environment with a new value (in place). putEnv-  :: forall e es. e :> es+  :: forall e es. (HasCallStack, e :> es)   => Env es -- ^ The environment.   -> EffectRep (DispatchOf e) e   -> IO () putEnv env e = do   (i, es) <- getLocation @e env-  writeSmallArray' es i (toAny e)+  writeSmallArray' es i (toAnyEffect e)  -- | Modify the data type in the environment and return a value (in place). stateEnv-  :: forall e es a. e :> es+  :: forall e es a. (HasCallStack, e :> es)   => Env es -- ^ The environment.-  -> (EffectRep (DispatchOf e) e -> IO (a, EffectRep (DispatchOf e) e))+  -> (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e))   -> IO a stateEnv env f = do   (i, es) <- getLocation @e env-  (a, e) <- f . fromAny =<< readSmallArray es i-  writeSmallArray' es i (toAny e)+  (a, e) <- f . fromAnyEffect <$> readSmallArray es i+  writeSmallArray' es i (toAnyEffect e)   pure a  -- | Modify the data type in the environment (in place). modifyEnv-  :: forall e es. e :> es+  :: forall e es. (HasCallStack, e :> es)   => Env es -- ^ The environment.-  -> (EffectRep (DispatchOf e) e -> IO (EffectRep (DispatchOf e) e))+  -> (EffectRep (DispatchOf e) e -> (EffectRep (DispatchOf e) e))   -> IO () modifyEnv env f = do   (i, es) <- getLocation @e env-  e <- f . fromAny =<< readSmallArray es i-  writeSmallArray' es i (toAny e)+  e <- f . fromAnyEffect <$> readSmallArray es i+  writeSmallArray' es i (toAnyEffect e)  -- | Determine location of the effect in the environment. getLocation-  :: forall e es. e :> es+  :: forall e es. (HasCallStack, e :> es)   => Env es-  -> IO (Int, SmallMutableArray RealWorld Any)+  -> IO (Int, SmallMutableArray RealWorld AnyEffect) getLocation (Env offset refs storage) = do-  let i       = offset + 2 * reifyIndex @e @es-      ref     = indexPrimArray refs  i-      version = indexPrimArray refs (i + 1)   Storage _ _ vs es _ <- readIORef' storage   storageVersion <- readPrimArray vs ref   -- If version of the reference is different than version in the storage, it@@ -356,26 +420,32 @@   -- referenced.   when (version /= storageVersion) $ do     error $ "version (" ++ show version ++ ") /= storageVersion ("-         ++ show storageVersion ++ ")"+         ++ show storageVersion ++ ")\n"+         ++ "If you're attempting to run an unlifting function outside "+         ++ "of the scope of effects it captures, have a look at "+         ++ "UnliftingStrategy (SeqForkUnlift)."   pure (ref, es)+  where+    Ref ref version = indexPrimArray refs (offset + reifyIndex @e @es)  ---------------------------------------- -- Internal helpers  -- | Create an empty storage.-emptyStorage :: IO Storage-emptyStorage = Storage 0 (noVersion + 1)+emptyStorage :: HasCallStack => IO Storage+emptyStorage = Storage 0 initialVersion   <$> newPrimArray 0-  <*> newSmallArray 0 undefinedData-  <*> newSmallArray 0 undefinedData+  <*> newSmallArray 0 undefinedEffect+  <*> newSmallArray 0 undefinedRelinker  -- | Insert an effect into the storage and return its reference. insertEffect-  :: IORef' Storage+  :: HasCallStack+  => IORef' Storage   -> EffectRep (DispatchOf e) e   -- ^ The representation of the effect.   -> Relinker (EffectRep (DispatchOf e)) e-  -> IO (Int, Int)+  -> IO Ref insertEffect storage e f = do   Storage size version vs0 es0 fs0 <- readIORef' storage   len0 <- getSizeofSmallMutableArray es0@@ -383,35 +453,39 @@     GT -> error $ "size (" ++ show size ++ ") > len0 (" ++ show len0 ++ ")"     LT -> do       writePrimArray   vs0 size version-      writeSmallArray' es0 size (toAny e)-      writeSmallArray' fs0 size (toAny f)-      writeIORef' storage $ Storage (size + 1) (version + 1) vs0 es0 fs0-      pure (size, version)+      writeSmallArray' es0 size (toAnyEffect e)+      writeSmallArray' fs0 size (toAnyRelinker f)+      writeIORef' storage $ Storage (size + 1) (bumpVersion version) vs0 es0 fs0+      pure $ Ref size version     EQ -> do       let len = doubleCapacity len0       vs <- newPrimArray len-      es <- newSmallArray len undefinedData-      fs <- newSmallArray len undefinedData+      es <- newSmallArray len undefinedEffect+      fs <- newSmallArray len undefinedRelinker       copyMutablePrimArray  vs 0 vs0 0 size       copySmallMutableArray es 0 es0 0 size       copySmallMutableArray fs 0 fs0 0 size       writePrimArray   vs size version-      writeSmallArray' es size (toAny e)-      writeSmallArray' fs size (toAny f)-      writeIORef' storage $ Storage (size + 1) (version + 1) vs es fs-      pure (size, version)+      writeSmallArray' es size (toAnyEffect e)+      writeSmallArray' fs size (toAnyRelinker f)+      writeIORef' storage $ Storage (size + 1) (bumpVersion version) vs es fs+      pure $ Ref size version  -- | Given a reference to an effect from the top of the stack, delete it from -- the storage.-deleteEffect :: IORef' Storage -> Int -> IO ()-deleteEffect storage ref = do-  Storage size version vs es fs <- readIORef' storage+deleteEffect :: HasCallStack => IORef' Storage -> Ref -> IO ()+deleteEffect storage (Ref ref version) = do+  Storage size currentVersion vs es fs <- readIORef' storage   when (ref /= size - 1) $ do     error $ "ref (" ++ show ref ++ ") /= size - 1 (" ++ show (size - 1) ++ ")"-  writePrimArray  vs ref noVersion-  writeSmallArray es ref undefinedData-  writeSmallArray fs ref undefinedData-  writeIORef' storage $ Storage (size - 1) version vs es fs+  storageVersion <- readPrimArray vs ref+  when (version /= storageVersion) $ do+    error $ "version (" ++ show version ++ ") /= storageVersion ("+         ++ show storageVersion ++ ")\n"+  writePrimArray  vs ref undefinedVersion+  writeSmallArray es ref undefinedEffect+  writeSmallArray fs ref undefinedRelinker+  writeIORef' storage $ Storage (size - 1) currentVersion vs es fs  -- | Relink the environment to use the new storage. relinkEnv :: IORef' Storage -> Env es -> IO (Env es)@@ -421,11 +495,30 @@ doubleCapacity :: Int -> Int doubleCapacity n = max 1 n * 2 -noVersion :: Int-noVersion = 0+undefinedVersion :: Version+undefinedVersion = Version 0 -undefinedData :: HasCallStack => a-undefinedData = error "undefined data"+initialVersion :: Version+initialVersion = Version 1++bumpVersion :: Version -> Version+bumpVersion (Version n) = Version (n + 1)++undefinedEffect :: HasCallStack => AnyEffect+undefinedEffect = toAnyEffect . errorWithoutStackTrace $ unlines+  [ "Undefined effect"+  , "Created at: " ++ prettyCallStack callStack+  ]++undefinedRelinker :: HasCallStack => AnyRelinker+undefinedRelinker = toAnyRelinker $ Relinker $ \_ _ -> do+  errorWithoutStackTrace $ unlines+    [ "Undefined relinker"+    , "Created at: " ++ prettyCallStack creationCallStack+    , "Called at: " ++ prettyCallStack callStack+    ]+  where+    creationCallStack = callStack  -- | A strict version of 'writeSmallArray'. writeSmallArray' :: SmallMutableArray RealWorld a -> Int -> a -> IO ()
src/Effectful/Internal/Monad.hs view
@@ -50,6 +50,7 @@    -- ** Low-level unlifts   , seqUnliftIO+  , seqForkUnliftIO   , concUnliftIO    -- * Dispatch@@ -73,16 +74,10 @@   , stateStaticRep   , stateStaticRepM   , localStaticRep--  -- *** Primitive operations-  , consEnv-  , getEnv-  , putEnv-  , stateEnv-  , modifyEnv   ) where  import Control.Applicative+import Control.Concurrent (myThreadId) import Control.Exception qualified as E import Control.Monad import Control.Monad.Base@@ -124,12 +119,12 @@ -- -- - Allows the effects to be handled in any order. newtype Eff (es :: [Effect]) a = Eff (Env es -> IO a)-  deriving (Monoid, Semigroup)+  deriving newtype (Monoid, Semigroup)  -- | Run a pure 'Eff' computation. -- -- For running computations with side effects see 'runEff'.-runPureEff :: Eff '[] a -> a+runPureEff :: HasCallStack => Eff '[] a -> a runPureEff (Eff m) =   -- unsafeDupablePerformIO is safe here since IOE was not on the stack, so no   -- IO with side effects was performed (unless someone sneakily introduced side@@ -144,7 +139,7 @@  -- | Peel off the constructor of 'Eff'. unEff :: Eff es a -> Env es -> IO a-unEff = \(Eff m) -> m+unEff (Eff m) = m  -- | Access the underlying 'IO' monad along with the environment. --@@ -188,7 +183,8 @@   => ((forall r. Eff es r -> IO r) -> IO a)   -- ^ Continuation with the unlifting function in scope.   -> Eff es a-withSeqEffToIO f = unsafeEff $ \es -> seqUnliftIO es f+withSeqEffToIO k = unsafeEff $ \es -> seqUnliftIO es k+{-# INLINE withSeqEffToIO #-}  -- | Create an unlifting function with the given strategy. --@@ -202,6 +198,7 @@   -> Eff es a withEffToIO strategy k = case strategy of   SeqUnlift      -> unsafeEff $ \es -> seqUnliftIO es k+  SeqForkUnlift  -> unsafeEff $ \es -> seqForkUnliftIO es k   ConcUnlift p b -> unsafeEff $ \es -> concUnliftIO es p b k {-# INLINE withEffToIO #-} @@ -215,8 +212,8 @@   -> ((forall r. Eff es r -> IO r) -> IO a)   -- ^ Continuation with the unlifting function in scope.   -> Eff es a-withConcEffToIO persistence limit f = unsafeEff $ \es ->-  concUnliftIO es persistence limit f+withConcEffToIO persistence limit k = unsafeEff $ \es ->+  concUnliftIO es persistence limit k {-# DEPRECATED withConcEffToIO "Use withEffToIO with the appropriate strategy." #-}  -- | Create an unlifting function with the 'SeqUnlift' strategy.@@ -227,8 +224,27 @@   -> ((forall r. Eff es r -> IO r) -> IO a)   -- ^ Continuation with the unlifting function in scope.   -> IO a-seqUnliftIO es k = seqUnlift k es unEff+seqUnliftIO es k = do+  tid0 <- myThreadId+  k $ \m -> do+    tid <- myThreadId+    if tid `eqThreadId` tid0+      then unEff m es+      else error+         $ "If you want to use the unlifting function to run Eff computations "+        ++ "in multiple threads, have a look at UnliftStrategy (ConcUnlift)." +-- | Create an unlifting function with the 'SeqForkUnlift' strategy.+seqForkUnliftIO+  :: HasCallStack+  => Env es+  -- ^ The environment.+  -> ((forall r. Eff es r -> IO r) -> IO a)+  -- ^ Continuation with the unlifting function in scope.+  -> IO a+seqForkUnliftIO es0 k = cloneEnv es0 >>= \es -> seqUnliftIO es k+{-# INLINE seqForkUnliftIO #-}+ -- | Create an unlifting function with the 'ConcUnlift' strategy. concUnliftIO   :: HasCallStack@@ -239,7 +255,10 @@   -> ((forall r. Eff es r -> IO r) -> IO a)   -- ^ Continuation with the unlifting function in scope.   -> IO a-concUnliftIO es persistence limit k = concUnlift persistence limit k es unEff+concUnliftIO es Ephemeral (Limited uses) = ephemeralConcUnlift es uses+concUnliftIO es Ephemeral Unlimited = ephemeralConcUnlift es maxBound+concUnliftIO es Persistent (Limited threads) = persistentConcUnlift es False threads+concUnliftIO es Persistent Unlimited = persistentConcUnlift es True maxBound  ---------------------------------------- -- Base@@ -279,7 +298,7 @@  -- | @since 2.2.0.0 instance NonDet :> es => Alternative (Eff es) where-  empty   = withFrozenCallStack (send Empty)+  empty   = send Empty   a <|> b = send (a :<|>: b)  -- | @since 2.2.0.0@@ -321,7 +340,7 @@ type instance DispatchOf Fail = Dynamic  instance Fail :> es => MonadFail (Eff es) where-  fail msg = withFrozenCallStack $ send (Fail msg)+  fail msg = send (Fail msg)  ---------------------------------------- -- IO@@ -339,7 +358,7 @@ -- | Run an 'Eff' computation with side effects. -- -- For running pure computations see 'runPureEff'.-runEff :: Eff '[IOE] a -> IO a+runEff :: HasCallStack => Eff '[IOE] a -> IO a runEff m = unEff m =<< consEnv (IOE SeqUnlift) dummyRelinker =<< emptyEnv  instance IOE :> es => MonadIO (Eff es) where@@ -387,7 +406,7 @@ data PrimStateEff  -- | Run an 'Eff' computation with primitive state-transformer actions.-runPrim :: IOE :> es => Eff (Prim : es) a -> Eff es a+runPrim :: (HasCallStack, IOE :> es) => Eff (Prim : es) a -> Eff es a runPrim = evalStaticRep Prim  instance Prim :> es => PrimMonad (Eff es) where@@ -411,23 +430,23 @@   -> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a)   -- ^ Continuation with the unlifting function in scope.   -> Eff (e : es) a-raiseWith strategy k = case strategy of-  SeqUnlift -> unsafeEff $ \ees -> do-    es <- tailEnv ees-    seqUnliftIO ees $ \unlift -> do+raiseWith strategy k = unsafeEff $ \ees -> do+  es <- tailEnv ees+  case strategy of+    SeqUnlift -> seqUnliftIO ees $ \unlift -> do       (`unEff` es) $ k $ unsafeEff_ . unlift-  ConcUnlift p l -> unsafeEff $ \ees -> do-    es <- tailEnv ees-    concUnliftIO ees p l $ \unlift -> do+    SeqForkUnlift -> seqForkUnliftIO ees $ \unlift -> do       (`unEff` es) $ k $ unsafeEff_ . unlift+    ConcUnlift p l -> concUnliftIO ees p l $ \unlift -> do+      (`unEff` es) $ k $ unsafeEff_ . unlift {-# INLINE raiseWith #-}  -- | Eliminate a duplicate effect from the top of the effect stack. subsume :: e :> es => Eff (e : es) a -> Eff es a subsume m = unsafeEff $ \es -> unEff m =<< subsumeEnv es --- | Allow for running an effect stack @xs@ within @es@ as long as @xs@ is a--- permutation (with possible duplicates) of a subset of @es@.+-- | Allow for running an effect stack @subEs@ within @es@ as long as @subEs@ is+-- a permutation (with possible duplicates) of a subset of @es@. -- -- Generalizes 'raise' and 'subsume'. --@@ -476,7 +495,7 @@ -- ... -- ...Couldn't match type ‘es1’ with ‘es2’ -- ...-inject :: Subset xs es => Eff xs a -> Eff es a+inject :: Subset subEs es => Eff subEs a -> Eff es a inject m = unsafeEff $ \es -> unEff m =<< injectEnv es  ----------------------------------------@@ -494,13 +513,13 @@ newtype LocalEnv (localEs :: [Effect]) (handlerEs :: [Effect]) = LocalEnv (Env localEs)  -- | Type signature of the effect handler.-type EffectHandler e es+type EffectHandler (e :: Effect) (es :: [Effect])   = forall a localEs. (HasCallStack, e :> localEs)   => LocalEnv localEs es   -- ^ Capture of the local environment for handling local 'Eff' computations   -- when @e@ is a higher order effect.   -> e (Eff localEs) a-  -- ^ The effect performed in the local environment.+  -- ^ The operation.   -> Eff es a  -- | An internal representation of dynamically dispatched effects, i.e. the@@ -515,7 +534,11 @@   pure $ Handler newHandlerEs handler  -- | Run a dynamically dispatched effect with the given handler.-runHandler :: DispatchOf e ~ Dynamic => Handler e -> Eff (e : es) a -> Eff es a+runHandler+  :: (HasCallStack, DispatchOf e ~ Dynamic)+  => Handler e+  -> Eff (e : es) a+  -> Eff es a runHandler e m = unsafeEff $ \es0 -> do   inlineBracket     (consEnv e relinkHandler es0)@@ -553,7 +576,7 @@ -- | Run a statically dispatched effect with the given initial representation -- and return the final value along with the final representation. runStaticRep-  :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)+  :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)   => StaticRep e -- ^ The initial representation.   -> Eff (e : es) a   -> Eff es (a, StaticRep e)@@ -566,7 +589,7 @@ -- | Run a statically dispatched effect with the given initial representation -- and return the final value, discarding the final representation. evalStaticRep-  :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)+  :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)   => StaticRep e -- ^ The initial representation.   -> Eff (e : es) a   -> Eff es a@@ -579,7 +602,7 @@ -- | Run a statically dispatched effect with the given initial representation -- and return the final representation, discarding the final value. execStaticRep-  :: (DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)+  :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es)   => StaticRep e -- ^ The initial representation.   -> Eff (e : es) a   -> Eff es (StaticRep e)@@ -590,42 +613,48 @@     (\es -> unEff m es *> getEnv es)  -- | Fetch the current representation of the effect.-getStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => Eff es (StaticRep e)+getStaticRep+  :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)+  => Eff es (StaticRep e) getStaticRep = unsafeEff $ \es -> getEnv es  -- | Set the current representation of the effect to the given value.-putStaticRep :: (DispatchOf e ~ Static sideEffects, e :> es) => StaticRep e -> Eff es ()+putStaticRep+  :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)+  => StaticRep e -> Eff es () putStaticRep s = unsafeEff $ \es -> putEnv es s  -- | Apply the function to the current representation of the effect and return a -- value. stateStaticRep-  :: (DispatchOf e ~ Static sideEffects, e :> es)+  :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)   => (StaticRep e -> (a, StaticRep e))   -- ^ The function to modify the representation.   -> Eff es a-stateStaticRep f = unsafeEff $ \es -> stateEnv es (pure . f)+stateStaticRep f = unsafeEff $ \es -> stateEnv es f  -- | Apply the monadic function to the current representation of the effect and -- return a value. stateStaticRepM-  :: (DispatchOf e ~ Static sideEffects, e :> es)+  :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)   => (StaticRep e -> Eff es (a, StaticRep e))   -- ^ The function to modify the representation.   -> Eff es a stateStaticRepM f = unsafeEff $ \es -> E.mask $ \unmask -> do-  stateEnv es $ unmask . (`unEff` es) . f+  (a, e) <- unmask . (`unEff` es) . f =<< getEnv es+  putEnv es e+  pure a  -- | Execute a computation with a temporarily modified representation of the -- effect. localStaticRep-  :: (DispatchOf e ~ Static sideEffects, e :> es)+  :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es)   => (StaticRep e -> StaticRep e)   -- ^ The function to temporarily modify the representation.   -> Eff es a   -> Eff es a localStaticRep f m = unsafeEff $ \es -> do   inlineBracket-    (stateEnv es $ \s -> pure (s, f s))+    (stateEnv es $ \s -> (s, f s))     (\s -> putEnv es s)     (\_ -> unEff m es)
src/Effectful/Internal/Unlift.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE MagicHash #-}+{-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} -- | Implementation of sequential and concurrent unlifts.@@ -12,12 +13,14 @@   , Limit(..)      -- * Unlifting functions-  , seqUnlift-  , concUnlift+  , ephemeralConcUnlift+  , persistentConcUnlift   ) where  import Control.Concurrent+import Control.Concurrent.MVar.Strict import Control.Monad+import Data.Coerce import Data.IntMap.Strict qualified as IM import GHC.Conc.Sync (ThreadId(..)) import GHC.Exts (mkWeak#, mkWeakNoFinalizer#)@@ -41,11 +44,59 @@   -- ^ The sequential strategy is the fastest and a default setting for   -- t'Effectful.IOE'. Any attempt of calling the unlifting function in threads   -- distinct from its creator will result in a runtime error.+  | SeqForkUnlift+  -- ^ Like 'SeqUnlift', but all unlifted actions will be executed in a cloned+  -- environment.+  --+  -- The main consequence is that thread local state is forked at the point of+  -- creation of the unlifting function and its modifications in unlifted+  -- actions will not affect the main thread of execution (and vice versa):+  --+  -- >>> import Effectful+  -- >>> import Effectful.State.Dynamic+  -- >>> :{+  --  action :: (IOE :> es, State Int :> es) => Eff es ()+  --  action = do+  --    modify @Int (+1)+  --    withEffToIO SeqForkUnlift $ \unlift -> unlift $ modify @Int (+2)+  --    modify @Int (+4)+  -- :}+  --+  -- >>> runEff . execStateLocal @Int 0 $ action+  -- 5+  --+  -- >>> runEff . execStateShared @Int 0 $ action+  -- 7+  --+  -- Because of this it's possible to safely use the unlifting function outside+  -- of the scope of effects it captures, e.g. by creating an @IO@ action that+  -- executes effectful operations and running it later:+  --+  -- >>> :{+  --   delayed :: UnliftStrategy -> IO (IO String)+  --   delayed strategy = runEff . evalStateLocal "Hey" $ do+  --     r <- withEffToIO strategy $ \unlift -> pure $ unlift get+  --     modify (++ "!!!")+  --     pure r+  -- :}+  --+  -- This doesn't work with the 'SeqUnlift' strategy because when the returned+  -- action runs, @State@ is no longer in scope:+  --+  -- >>> join $ delayed SeqUnlift+  -- *** Exception: version (...) /= storageVersion (0)+  -- ...+  --+  -- However, it does with the 'SeqForkUnlift' strategy:+  --+  -- >>> join $ delayed SeqForkUnlift+  -- "Hey"+  --   | ConcUnlift !Persistence !Limit   -- ^ The concurrent strategy makes it possible for the unlifting function to   -- be called in threads distinct from its creator. See 'Persistence' and   -- 'Limit' settings for more information.-  deriving (Eq, Generic, Ord, Show)+  deriving stock (Eq, Generic, Ord, Show)  -- | Persistence setting for the 'ConcUnlift' strategy. --@@ -65,7 +116,7 @@   | Persistent   -- ^ Persist the environment between calls to the unlifting function within a   -- particular thread.-  deriving (Eq, Generic, Ord, Show)+  deriving stock (Eq, Generic, Ord, Show)  -- | Limit setting for the 'ConcUnlift' strategy. data Limit@@ -84,60 +135,21 @@   -- when called in @N@ threads and @K+1@ copies when called in @K < N@ threads.   | Unlimited   -- ^ Unlimited use of the unlifting function.-  deriving (Eq, Generic, Ord, Show)+  deriving stock (Eq, Generic, Ord, Show)  ---------------------------------------- -- Unlift functions --- | Sequential unlift.-seqUnlift-  :: HasCallStack-  => ((forall r. m r -> IO r) -> IO a)-  -> Env es-  -> (forall r. m r -> Env es -> IO r)-  -> IO a-seqUnlift k es unEff = do-  tid0 <- myThreadId-  k $ \m -> do-    tid <- myThreadId-    if tid `eqThreadId` tid0-      then unEff m es-      else error-         $ "If you want to use the unlifting function to run Eff computations "-        ++ "in multiple threads, have a look at UnliftStrategy (ConcUnlift)."---- | Concurrent unlift.-concUnlift-  :: HasCallStack-  => Persistence-  -> Limit-  -> ((forall r. m r -> IO r) -> IO a)-  -> Env es-  -> (forall r. m r -> Env es -> IO r)-  -> IO a-concUnlift Ephemeral (Limited uses) k =-  ephemeralConcUnlift uses k-concUnlift Ephemeral Unlimited k =-  ephemeralConcUnlift maxBound k-concUnlift Persistent (Limited threads) k =-  persistentConcUnlift False threads k-concUnlift Persistent Unlimited k =-  persistentConcUnlift True maxBound k--------------------------------------------- Internal- -- | Concurrent unlift that doesn't preserve the environment between calls to -- the unlifting function in threads other than its creator. ephemeralConcUnlift-  :: HasCallStack-  => Int+  :: (HasCallStack, forall r. Coercible (m r) (Env es -> IO r))+  => Env es+  -> Int   -- ^ Number of permitted uses of the unlift function.   -> ((forall r. m r -> IO r) -> IO a)-  -> Env es-  -> (forall r. m r -> Env es -> IO r)   -> IO a-ephemeralConcUnlift uses k es0 unEff = do+ephemeralConcUnlift es0 uses k = do   unless (uses > 0) $ do     error $ "Invalid number of uses: " ++ show uses   tid0 <- myThreadId@@ -158,21 +170,20 @@         n -> do           es <- cloneEnv esTemplate           pure (n - 1, es)-    unEff m es+    coerce m es {-# NOINLINE ephemeralConcUnlift #-}  -- | Concurrent unlift that preserves the environment between calls to the -- unlifting function within a particular thread. persistentConcUnlift-  :: HasCallStack-  => Bool+  :: (HasCallStack, forall r. Coercible (m r) (Env es -> IO r))+  => Env es+  -> Bool   -> Int   -- ^ Number of threads that are allowed to use the unlift function.   -> ((forall r. m r -> IO r) -> IO a)-  -> Env es-  -> (forall r. m r -> Env es -> IO r)   -> IO a-persistentConcUnlift cleanUp threads k es0 unEff = do+persistentConcUnlift es0 cleanUp threads k = do   unless (threads > 0) $ do     error $ "Invalid number of threads: " ++ show threads   tid0 <- myThreadId@@ -211,14 +222,14 @@                     , teEntries  = addThreadData wkTid i wkTidEs $ teEntries te                     }               pure (newEntries, es)-    unEff m es+    coerce m es {-# NOINLINE persistentConcUnlift #-}  ---------------------------------------- -- Data types  newtype EntryId = EntryId Int-  deriving Eq+  deriving newtype Eq  newEntryId :: EntryId newEntryId = EntryId 0@@ -295,7 +306,7 @@ ----------------------------------------  deleteThreadData :: Int -> EntryId -> MVar' (ThreadEntries es) -> IO ()-deleteThreadData wkTid i v = modifyMVar_' v $ \te -> do+deleteThreadData wkTid i v = modifyMVar'_ v $ \te -> do   pure ThreadEntries     { teCapacity = case teCapacity te of         -- If the template copy of the environment hasn't been consumed
src/Effectful/Internal/Utils.hs view
@@ -14,20 +14,6 @@   , toAny   , fromAny -    -- * Strict 'IORef'-  , IORef'-  , newIORef'-  , readIORef'-  , writeIORef'--    -- * Strict 'MVar'-  , MVar'-  , toMVar'-  , newMVar'-  , readMVar'-  , modifyMVar'-  , modifyMVar_'-     -- * Unique   , Unique   , newUnique@@ -36,9 +22,7 @@   , thawCallStack   ) where -import Control.Concurrent.MVar import Control.Exception-import Data.IORef import Data.Primitive.ByteArray import GHC.Conc.Sync (ThreadId(..)) import GHC.Exts (Any, RealWorld)@@ -125,49 +109,6 @@  fromAny :: Any -> a fromAny = unsafeCoerce---------------------------------------------- | A strict variant of 'IORef'.-newtype IORef' a = IORef' (IORef a)-  deriving Eq--newIORef' :: a -> IO (IORef' a)-newIORef' a = a `seq` (IORef' <$> newIORef a)--readIORef' :: IORef' a -> IO a-readIORef' (IORef' var) = readIORef var--writeIORef' :: IORef' a -> a -> IO ()-writeIORef' (IORef' var) a = a `seq` writeIORef var a---------------------------------------------- | A strict variant of 'MVar'.-newtype MVar' a = MVar' (MVar a)-  deriving Eq--toMVar' :: MVar a -> IO (MVar' a)-toMVar' var = do-  let var' = MVar' var-  modifyMVar_' var' pure-  pure var'--newMVar' :: a -> IO (MVar' a)-newMVar' a = a `seq` (MVar' <$> newMVar a)--readMVar' :: MVar' a -> IO a-readMVar' (MVar' var) = readMVar var--modifyMVar' :: MVar' a -> (a -> IO (a, r)) -> IO r-modifyMVar' (MVar' var) action = modifyMVar var $ \a0 -> do-  (a, r) <- action a0-  a `seq` pure (a, r)--modifyMVar_' :: MVar' a -> (a -> IO a) -> IO ()-modifyMVar_' (MVar' var) action = modifyMVar_ var $ \a0 -> do-  a <- action a0-  a `seq` pure a  ---------------------------------------- 
src/Effectful/Labeled.hs view
@@ -1,14 +1,13 @@ {-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE PolyKinds #-} -- | Labeled effects. --+-- Any effect can be assigned multiple labels so you have more than one+-- available simultaneously.+-- -- @since 2.3.0.0 module Effectful.Labeled-  ( -- * Example-    -- $example--    -- * Effect-    Labeled+  ( -- * Effect+    Labeled(..)      -- ** Handlers   , runLabeled@@ -22,58 +21,49 @@ import Effectful import Effectful.Dispatch.Static --- $example+-- | Assign a label to an effect. ----- An effect can be assigned multiple labels and you can have all of them--- available at the same time.+-- The constructor is for sending labeled operations of a dynamically dispatched+-- effect to the handler: ----- >>> import Effectful.Reader.Static+-- >>> import Effectful.Dispatch.Dynamic -- -- >>> :{---  action---    :: ( Labeled "a" (Reader String) :> es---       , Labeled "b" (Reader String) :> es---       , Reader String :> es---       )---    => Eff es String---  action = do---    a <- labeled @"b" @(Reader String) $ do---      labeled @"a" @(Reader String) $ do---        ask---    b <- labeled @"b" @(Reader String) $ do---      ask---    pure $ a ++ b+--   data X :: Effect where+--     X :: X m Int+--   type instance DispatchOf X = Dynamic -- :} -- -- >>> :{---  runPureEff @String---    . runLabeled @"a" (runReader "a")---    . runLabeled @"b" (runReader "b")---    . runReader "c"---    $ action+--   runPureEff . runLabeled @"x" (interpret_ $ \X -> pure 333) $ do+--     send $ Labeled @"x" X -- :}--- "ab"---- | Assign a label to an effect.-data Labeled (label :: k) (e :: Effect) :: Effect+-- 333+--+newtype Labeled (label :: k) (e :: Effect) :: Effect where+  -- | @since 2.4.0.0+  Labeled :: forall label e m a. e m a -> Labeled label e m a -type instance DispatchOf (Labeled label e) = Static NoSideEffects+type instance DispatchOf (Labeled label e) = DispatchOf e  data instance StaticRep (Labeled label e)  -- | Run a 'Labeled' effect with a given effect handler. runLabeled   :: forall label e es a b-   . (Eff (e : es) a -> Eff es b)+   . HasCallStack+  => (Eff (e : es) a -> Eff es b)   -- ^ The effect handler.   -> Eff (Labeled label e : es) a   -> Eff es b runLabeled runE m = runE (fromLabeled m) --- | Bring an effect into scope to be able to run its operations.+-- | Bring an effect into scope without a label.+--+-- Useful for running code written with the non-labeled effect in mind. labeled   :: forall label e es a-   . Labeled label e :> es+   . (HasCallStack, Labeled label e :> es)   => Eff (e : es) a   -- ^ The action using the effect.   -> Eff es a
+ src/Effectful/Labeled/Error.hs view
@@ -0,0 +1,139 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+-- | Convenience functions for the 'Labeled' 'Error' effect.+--+-- @since 2.4.0.0+module Effectful.Labeled.Error+  ( -- * Effect+    Error(..)++    -- ** Handlers+  , runError+  , runErrorWith+  , runErrorNoCallStack+  , runErrorNoCallStackWith++    -- ** Operations+  , throwErrorWith+  , throwError+  , throwError_+  , catchError+  , handleError+  , tryError++    -- * Re-exports+  , E.HasCallStack+  , E.CallStack+  , E.getCallStack+  , E.prettyCallStack+  ) where++import GHC.Stack (withFrozenCallStack)++import Effectful+import Effectful.Dispatch.Dynamic+import Effectful.Labeled+import Effectful.Error.Dynamic (Error(..))+import Effectful.Error.Dynamic qualified as E++-- | Handle errors of type @e@ (via "Effectful.Error.Static").+runError+  :: forall label e es a+   . HasCallStack+  => Eff (Labeled label (Error e) : es) a+  -> Eff es (Either (E.CallStack, e) a)+runError = runLabeled @label E.runError++-- | Handle errors of type @e@ (via "Effectful.Error.Static") with a specific+-- error handler.+runErrorWith+  :: forall label e es a+   . HasCallStack+  => (E.CallStack -> e -> Eff es a)+  -- ^ The error handler.+  -> Eff (Labeled label (Error e) : es) a+  -> Eff es a+runErrorWith = runLabeled @label . E.runErrorWith++-- | Handle errors of type @e@ (via "Effectful.Error.Static"). In case of an+-- error discard the 'E.CallStack'.+runErrorNoCallStack+  :: forall label e es a+   . HasCallStack+  => Eff (Labeled label (Error e) : es) a+  -> Eff es (Either e a)+runErrorNoCallStack = runLabeled @label E.runErrorNoCallStack++-- | Handle errors of type @e@ (via "Effectful.Error.Static") with a specific+-- error handler. In case of an error discard the 'CallStack'.+runErrorNoCallStackWith+  :: forall label e es a+   . HasCallStack+  => (e -> Eff es a)+  -- ^ The error handler.+  -> Eff (Labeled label (Error e) : es) a+  -> Eff es a+runErrorNoCallStackWith = runLabeled @label . E.runErrorNoCallStackWith++-- | Throw an error of type @e@ and specify a display function in case a+-- third-party code catches the internal exception and 'show's it.+throwErrorWith+  :: forall label e es a+   . (HasCallStack, Labeled label (Error e) :> es)+  => (e -> String)+  -- ^ The display function.+  -> e+  -- ^ The error.+  -> Eff es a+throwErrorWith display =+  withFrozenCallStack send . Labeled @label . ThrowErrorWith display++-- | Throw an error of type @e@ with 'show' as a display function.+throwError+  :: forall label e es a+   . (HasCallStack, Labeled label (Error e) :> es, Show e)+  => e+  -- ^ The error.+  -> Eff es a+throwError = withFrozenCallStack (throwErrorWith @label) show++-- | Throw an error of type @e@ with no display function.+throwError_+  :: forall label e es a+   . (HasCallStack, Labeled label (Error e) :> es)+  => e+  -- ^ The error.+  -> Eff es a+throwError_ = withFrozenCallStack (throwErrorWith @label) (const "<opaque>")++-- | Handle an error of type @e@.+catchError+  :: forall label e es a+   . (HasCallStack, Labeled label (Error e) :> es)+  => Eff es a+  -- ^ The inner computation.+  -> (E.CallStack -> e -> Eff es a)+  -- ^ A handler for errors in the inner computation.+  -> Eff es a+catchError m = send . Labeled @label . CatchError m++-- | The same as @'flip' 'catchError'@, which is useful in situations where the+-- code for the handler is shorter.+handleError+  :: forall label e es a+   . (HasCallStack, Labeled label (Error e) :> es)+  => (E.CallStack -> e -> Eff es a)+  -- ^ A handler for errors in the inner computation.+  -> Eff es a+  -- ^ The inner computation.+  -> Eff es a+handleError = flip (catchError @label)++-- | Similar to 'catchError', but returns an 'Either' result which is a 'Right'+-- if no error was thrown and a 'Left' otherwise.+tryError+  :: forall label e es a+   . (HasCallStack, Labeled label (Error e) :> es)+  => Eff es a+  -- ^ The inner computation.+  -> Eff es (Either (E.CallStack, e) a)+tryError m = catchError @label (Right <$> m) (\es e -> pure $ Left (es, e))
+ src/Effectful/Labeled/Reader.hs view
@@ -0,0 +1,67 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+-- | Convenience functions for the 'Labeled' 'Reader' effect.+--+-- @since 2.4.0.0+module Effectful.Labeled.Reader+  ( -- * Effect+    Reader(..)++    -- ** Handlers+  , runReader++    -- ** Operations+  , ask+  , asks+  , local+  ) where++import Effectful+import Effectful.Dispatch.Dynamic+import Effectful.Labeled+import Effectful.Reader.Dynamic (Reader(..))+import Effectful.Reader.Dynamic qualified as R++-- | Run the 'Reader' effect with the given initial environment (via+-- "Effectful.Reader.Static").+runReader+  :: forall label r es a+   . HasCallStack+  => r+  -- ^ The initial environment.+  -> Eff (Labeled label (Reader r) : es) a+  -> Eff es a+runReader = runLabeled @label . R.runReader++----------------------------------------+-- Operations++-- | Fetch the value of the environment.+ask+  :: forall label r es+  . (HasCallStack, Labeled label (Reader r) :> es)+  => Eff es r+ask = send $ Labeled @label Ask++-- | Retrieve a function of the current environment.+--+-- @'asks' f ≡ f '<$>' 'ask'@+asks+  :: forall label r es a+   . (HasCallStack, Labeled label (Reader r) :> es)+  => (r -> a)+  -- ^ The function to apply to the environment.+  -> Eff es a+asks f = f <$> ask @label++-- | Execute a computation in a modified environment.+--+-- @'runReader' r ('local' f m) ≡ 'runReader' (f r) m@+--+local+  :: forall label r es a+   . (HasCallStack, Labeled label (Reader r) :> es)+  => (r -> r)+  -- ^ The function to modify the environment.+  -> Eff es a+  -> Eff es a+local f = send . Labeled @label . Local f
+ src/Effectful/Labeled/State.hs view
@@ -0,0 +1,177 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+-- | Convenience functions for the 'Labeled' 'State' effect.+--+-- @since 2.4.0.0+module Effectful.Labeled.State+  ( -- * Effect+    State(..)++    -- ** Handlers++    -- *** Local+  , runStateLocal+  , evalStateLocal+  , execStateLocal++    -- *** Shared+  , runStateShared+  , evalStateShared+  , execStateShared++    -- ** Operations+  , get+  , gets+  , put+  , state+  , modify+  , stateM+  , modifyM+  ) where++import Effectful+import Effectful.Dispatch.Dynamic+import Effectful.Labeled+import Effectful.State.Dynamic (State(..))+import Effectful.State.Dynamic qualified as S++----------------------------------------+-- Local++-- | Run the 'State' effect with the given initial state and return the final+-- value along with the final state (via "Effectful.State.Static.Local").+runStateLocal+  :: forall label s es a+   . HasCallStack+  => s+   -- ^ The initial state.+  -> Eff (Labeled label (State s) : es) a+  -> Eff es (a, s)+runStateLocal = runLabeled @label . S.runStateLocal++-- | Run the 'State' effect with the given initial state and return the final+-- value, discarding the final state (via "Effectful.State.Static.Local").+evalStateLocal+  :: forall label s es a+   . HasCallStack+  => s+   -- ^ The initial state.+  -> Eff (Labeled label (State s) : es) a+  -> Eff es a+evalStateLocal = runLabeled @label . S.evalStateLocal++-- | Run the 'State' effect with the given initial state and return the final+-- state, discarding the final value (via "Effectful.State.Static.Local").+execStateLocal+  :: forall label s es a+   . HasCallStack+  => s+   -- ^ The initial state.+  -> Eff (Labeled label (State s) : es) a+  -> Eff es s+execStateLocal = runLabeled @label . S.execStateLocal++----------------------------------------+-- Shared++-- | Run the 'State' effect with the given initial state and return the final+-- value along with the final state (via "Effectful.State.Static.Shared").+runStateShared+  :: forall label s es a+   . HasCallStack+  => s+   -- ^ The initial state.+  -> Eff (Labeled label (State s) : es) a+  -> Eff es (a, s)+runStateShared = runLabeled @label . S.runStateShared++-- | Run the 'State' effect with the given initial state and return the final+-- value, discarding the final state (via "Effectful.State.Static.Shared").+evalStateShared+  :: forall label s es a+   . HasCallStack+  => s+   -- ^ The initial state.+  -> Eff (Labeled label (State s) : es) a+  -> Eff es a+evalStateShared = runLabeled @label . S.evalStateShared++-- | Run the 'State' effect with the given initial state and return the final+-- state, discarding the final value (via "Effectful.State.Static.Shared").+execStateShared+  :: forall label s es a+   . HasCallStack+  => s+   -- ^ The initial state.+  -> Eff (Labeled label (State s) : es) a+  -> Eff es s+execStateShared = runLabeled @label . S.execStateShared++----------------------------------------+-- Operations++-- | Fetch the current value of the state.+get+  :: forall label s es+   . (HasCallStack, Labeled label (State s) :> es)+  => Eff es s+get = send $ Labeled @label Get++-- | Get a function of the current state.+--+-- @'gets' f ≡ f '<$>' 'get'@+gets+  :: forall label s es a+   . (HasCallStack, Labeled label (State s) :> es)+  => (s -> a)+  -- ^ .+  -> Eff es a+gets f = f <$> get @label++-- | Set the current state to the given value.+put+  :: forall label s es+   . (HasCallStack, Labeled label (State s) :> es)+  => s+  -- ^ .+  -> Eff es ()+put = send . Labeled @label . Put++-- | Apply the function to the current state and return a value.+state+  :: forall label s es a+   . (HasCallStack, Labeled label (State s) :> es)+  => (s -> (a, s))+  -- ^ .+  -> Eff es a+state = send . Labeled @label . State++-- | Apply the function to the current state.+--+-- @'modify' f ≡ 'state' (\\s -> ((), f s))@+modify+  :: forall label s es+   . (HasCallStack, Labeled label (State s) :> es)+  => (s -> s)+  -- ^ .+  -> Eff es ()+modify f = state @label (\s -> ((), f s))++-- | Apply the monadic function to the current state and return a value.+stateM+  :: forall label s es a+   . (HasCallStack, Labeled label (State s) :> es)+  => (s -> Eff es (a, s))+  -- ^ .+  -> Eff es a+stateM = send . Labeled @label . StateM++-- | Apply the monadic function to the current state.+--+-- @'modifyM' f ≡ 'stateM' (\\s -> ((), ) '<$>' f s)@+modifyM+  :: forall label s es+   . (HasCallStack, Labeled label (State s) :> es)+  => (s -> Eff es s)+  -- ^ .+  -> Eff es ()+modifyM f = stateM @label (\s -> ((), ) <$> f s)
+ src/Effectful/Labeled/Writer.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+-- | Convenience functions for the 'Labeled' 'Writer' effect.+--+-- @since 2.4.0.0+module Effectful.Labeled.Writer+  ( -- * Effect+    Writer(..)++    -- ** Handlers++    -- *** Local+  , runWriterLocal+  , execWriterLocal++    -- *** Shared+  , runWriterShared+  , execWriterShared++    -- * Operations+  , tell+  , listen+  , listens+  ) where++import Effectful+import Effectful.Dispatch.Dynamic+import Effectful.Labeled+import Effectful.Writer.Dynamic (Writer(..))+import Effectful.Writer.Dynamic qualified as W++----------------------------------------+-- Local++-- | Run the 'Writer' effect and return the final value along with the final+-- output (via "Effectful.Writer.Static.Local").+runWriterLocal+  :: forall label w es a+   . (HasCallStack, Monoid w)+  => Eff (Labeled label (Writer w) : es)+  a -> Eff es (a, w)+runWriterLocal = runLabeled @label W.runWriterLocal++-- | Run a 'Writer' effect and return the final output, discarding the final+-- value (via "Effectful.Writer.Static.Local").+execWriterLocal+  :: forall label w es a+   . (HasCallStack, Monoid w)+  => Eff (Labeled label (Writer w) : es) a+  -> Eff es w+execWriterLocal = runLabeled @label W.execWriterLocal++----------------------------------------+-- Shared++-- | Run the 'Writer' effect and return the final value along with the final+-- output (via "Effectful.Writer.Static.Shared").+runWriterShared+  :: forall label w es a+   . (HasCallStack, Monoid w)+  => Eff (Labeled label (Writer w) : es) a+  -> Eff es (a, w)+runWriterShared = runLabeled @label W.runWriterShared++-- | Run the 'Writer' effect and return the final output, discarding the final+-- value (via "Effectful.Writer.Static.Shared").+execWriterShared+  :: forall label w es a+   . (HasCallStack, Monoid w)+  => Eff (Labeled label (Writer w) : es) a+  -> Eff es w+execWriterShared = runLabeled @label W.execWriterShared++----------------------------------------+-- Operations++-- | Append the given output to the overall output of the 'Writer'.+tell+  :: forall label w es+   . (HasCallStack, Labeled label (Writer w) :> es)+  => w+  -> Eff es ()+tell = send . Labeled @label . Tell++-- | Execute an action and append its output to the overall output of the+-- 'Writer'.+listen+  :: forall label w es a+   . (HasCallStack, Labeled label (Writer w) :> es)+  => Eff es a+  -> Eff es (a, w)+listen = send . Labeled @label . Listen++-- | Execute an action and append its output to the overall output of the+-- 'Writer', then return the final value along with a function of the recorded+-- output.+--+-- @'listens' f m ≡ 'Data.Bifunctor.second' f '<$>' 'listen' m@+listens+  :: forall label w es a b+   . (HasCallStack, Labeled label (Writer w) :> es)+  => (w -> b)+  -> Eff es a+  -> Eff es (a, b)+listens f m = do+  (a, w) <- listen @label m+  pure (a, f w)
src/Effectful/NonDet.hs view
@@ -40,9 +40,14 @@ -- -- @since 2.2.0.0 data OnEmptyPolicy-  = OnEmptyKeep     -- ^ Keep modifications on 'Empty'.-  | OnEmptyRollback -- ^ Rollback modifications on 'Empty'.-  deriving (Eq, Generic, Ord, Show)+  = OnEmptyKeep+  -- ^ Keep modifications on 'Empty'.+  | OnEmptyRollback+  -- ^ Rollback modifications on 'Empty'.+  --+  -- /Note:/ state modifications are rolled back on 'Empty' only. In particular,+  -- they are __not__ rolled back on exceptions.+  deriving stock (Eq, Generic, Ord, Show)  -- | Run the 'NonDet' effect with a given 'OnEmptyPolicy'. --@@ -50,33 +55,52 @@ -- computation calls 'Empty'. -- -- @since 2.2.0.0-runNonDet :: OnEmptyPolicy -> Eff (NonDet : es) a -> Eff es (Either CallStack a)+runNonDet+  :: HasCallStack+  => OnEmptyPolicy+  -> Eff (NonDet : es) a+  -> Eff es (Either CallStack a) runNonDet = \case   OnEmptyKeep     -> runNonDetKeep   OnEmptyRollback -> runNonDetRollback -runNonDetKeep :: Eff (NonDet : es) a -> Eff es (Either CallStack a)-runNonDetKeep = reinterpret (fmap noError . runError @()) $ \env -> \case-  Empty       -> throwError ()+runNonDetKeep+  :: HasCallStack+  => Eff (NonDet : es) a+  -> Eff es (Either CallStack a)+runNonDetKeep = reinterpret (fmap noError . runError @ErrorEmpty) $ \env -> \case+  Empty       -> throwError ErrorEmpty   m1 :<|>: m2 -> localSeqUnlift env $ \unlift -> do-    mr <- (Just <$> unlift m1) `catchError` \_ () -> pure Nothing+    mr <- (Just <$> unlift m1) `catchError` \_ ErrorEmpty -> pure Nothing     case mr of       Just r  -> pure r       Nothing -> unlift m2 -runNonDetRollback :: Eff (NonDet : es) a -> Eff es (Either CallStack a)-runNonDetRollback = reinterpret (fmap noError . runError @()) $ \env -> \case-  Empty       -> throwError ()+runNonDetRollback+  :: HasCallStack+  => Eff (NonDet : es) a+  -> Eff es (Either CallStack a)+runNonDetRollback = reinterpret setup $ \env -> \case+  Empty       -> throwError ErrorEmpty   m1 :<|>: m2 -> do     backupEnv <- cloneLocalEnv env     localSeqUnlift env $ \unlift -> do-      mr <- (Just <$> unlift m1) `catchError` \_ () -> do+      mr <- (Just <$> unlift m1) `catchError` \_ ErrorEmpty -> do         -- If m1 failed, roll back the environment.         restoreLocalEnv env backupEnv         pure Nothing       case mr of         Just r  -> pure r         Nothing -> unlift m2+  where+    setup action = do+      backupEs <- unsafeEff cloneEnv+      runError @ErrorEmpty action >>= \case+        Right r -> pure $ Right r+        Left (cs, _) -> do+          -- If the whole action failed, roll back the environment.+          unsafeEff $ \es -> restoreEnv es backupEs+          pure $ Left cs  ---------------------------------------- @@ -85,7 +109,7 @@ -- -- @since 2.2.0.0 emptyEff :: (HasCallStack, NonDet :> es) => Eff es a-emptyEff = withFrozenCallStack $ send Empty+emptyEff = withFrozenCallStack send Empty  -- | Specialized version of 'asum' with the 'HasCallStack' constraint for -- tracking purposes.@@ -97,16 +121,24 @@ ---------------------------------------- -- Internal helpers +-- | Internal error type for the Empty action. Better than '()' in case it+-- escapes the scope of 'runNonDet' and shows up in error messages.+data ErrorEmpty = ErrorEmpty+instance Show ErrorEmpty where+  show ErrorEmpty = "Effectful.NonDet.ErrorEmpty"+ noError :: Either (cs, e) a -> Either cs a noError = either (Left . fst) Right  cloneLocalEnv-  :: LocalEnv localEs handlerEs+  :: HasCallStack+  => LocalEnv localEs handlerEs   -> Eff es (LocalEnv localEs handlerEs) cloneLocalEnv = coerce . unsafeEff_ . cloneEnv . coerce  restoreLocalEnv-  :: LocalEnv localEs handlerEs+  :: HasCallStack+  => LocalEnv localEs handlerEs   -> LocalEnv localEs handlerEs   -> Eff es () restoreLocalEnv dest src = unsafeEff_ $ restoreEnv (coerce dest) (coerce src)
src/Effectful/Provider.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ImplicitParams #-} -- | Turn an effect handler into an effectful operation. -- -- @since 2.3.0.0@@ -25,6 +26,7 @@ import Data.Functor.Identity import Data.Kind (Type) import Data.Primitive.PrimArray+import GHC.Stack  import Effectful import Effectful.Dispatch.Static@@ -35,9 +37,9 @@ -- $example -- -- >>> import Control.Monad.IO.Class+-- >>> import Data.Map.Strict qualified as M -- >>> import Effectful.Dispatch.Dynamic -- >>> import Effectful.State.Static.Local--- >>> import qualified Data.Map.Strict as M -- -- Given an effect: --@@ -74,7 +76,7 @@ --     => FilePath --     -> Eff (Write : es) a --     -> Eff es a---   runWriteIO fp = interpret $ \_ -> \case+--   runWriteIO fp = interpret_ $ \case --     Write msg -> liftIO . putStrLn $ fp ++ ": " ++ msg -- :} --@@ -84,7 +86,7 @@ --     => FilePath --     -> Eff (Write : es) a --     -> Eff es a---   runWritePure fp = interpret $ \_ -> \case+--   runWritePure fp = interpret_ $ \case --     Write msg -> modify $ M.insertWith (++) fp [msg] -- :} --@@ -122,55 +124,64 @@ type instance DispatchOf (Provider e input f) = Static NoSideEffects  data instance StaticRep (Provider e input f) where-  Provider :: !(Env handlerEs)-           -> !(forall r. input -> Eff (e : handlerEs) r -> Eff handlerEs (f r))-           -> StaticRep (Provider e input f)+  Provider+    :: !(Env handlerEs)+    -> !(forall r. HasCallStack => input -> Eff (e : handlerEs) r -> Eff handlerEs (f r))+    -> StaticRep (Provider e input f)  -- | Run the 'Provider' effect with a given effect handler. runProvider-  :: (forall r. input -> Eff (e : es) r -> Eff es (f r))+  :: HasCallStack+  => (forall r. HasCallStack => input -> Eff (e : es) r -> Eff es (f r))   -- ^ The effect handler.   -> Eff (Provider e input f : es) a   -> Eff es a-runProvider run m = unsafeEff $ \es0 -> do+runProvider provider m = unsafeEff $ \es0 -> do   inlineBracket-    (consEnv (Provider es0 run) relinkProvider es0)+    (consEnv (mkProvider es0) relinkProvider es0)     unconsEnv     (\es -> unEff m es)+  where+    -- Corresponds to withFrozenCallStack in provideWith.+    mkProvider es = Provider es (let ?callStack = thawCallStack ?callStack in provider)  -- | Run the 'Provider' effect with a given effect handler that doesn't change -- its return type. runProvider_-  :: (forall r. input -> Eff (e : es) r -> Eff es r)+  :: HasCallStack+  => (forall r. HasCallStack => input -> Eff (e : es) r -> Eff es r)   -- ^ The effect handler.   -> Eff (Provider_ e input : es) a   -> Eff es a-runProvider_ run = runProvider $ \input -> coerce . run input+runProvider_ provider = runProvider $ \input -> coerce . provider input  -- | Run the effect handler.-provide :: Provider e () f :> es => Eff (e : es) a -> Eff es (f a)+provide :: (HasCallStack, Provider e () f :> es) => Eff (e : es) a -> Eff es (f a) provide = provideWith ()  -- | Run the effect handler with unchanged return type.-provide_ :: Provider_ e () :> es => Eff (e : es) a -> Eff es a+provide_ :: (HasCallStack, Provider_ e () :> es) => Eff (e : es) a -> Eff es a provide_ = provideWith_ ()  -- | Run the effect handler with a given input. provideWith-  :: Provider e input f :> es+  :: (HasCallStack, Provider e input f :> es)   => input   -- ^ The input to the effect handler.   -> Eff (e : es) a   -> Eff es (f a) provideWith input action = unsafeEff $ \es -> do-  Provider handlerEs run <- getEnv es-  (`unEff` handlerEs) . run input . unsafeEff $ \eHandlerEs -> do-    unEff action =<< copyRef eHandlerEs es+  Provider handlerEs handler <- getEnv es+  (`unEff` handlerEs)+    -- Corresponds to thawCallStack in runProvider.+    . withFrozenCallStack handler input+    . unsafeEff $ \eProviderEs -> do+    unEff action =<< copyRef eProviderEs es  -- | Run the effect handler that doesn't change its return type with a given -- input. provideWith_-  :: Provider_ e input :> es+  :: (HasCallStack, Provider_ e input :> es)   => input   -- ^ The input to the effect handler.   -> Eff (e : es) a@@ -188,13 +199,17 @@   newHandlerEs <- relink handlerEs   pure $ Provider newHandlerEs run -copyRef :: Env (e : handlerEs) -> Env es -> IO (Env (e : es))+copyRef+  :: HasCallStack+  => Env (e : handlerEs)+  -> Env es+  -> IO (Env (e : es)) copyRef (Env hoffset hrefs hstorage) (Env offset refs0 storage) = do   when (hstorage /= storage) $ do     error "storages do not match"   let size = sizeofPrimArray refs0 - offset-  mrefs <- newPrimArray (size + 2)-  copyPrimArray mrefs 0 hrefs hoffset 2-  copyPrimArray mrefs 2 refs0 offset size+  mrefs <- newPrimArray (size + 1)+  writePrimArray mrefs 0 $ indexPrimArray hrefs hoffset+  copyPrimArray mrefs 1 refs0 offset size   refs <- unsafeFreezePrimArray mrefs   pure $ Env 0 refs storage
src/Effectful/Provider/List.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ImplicitParams #-} -- | Turn a handler of multiple effects into an effectful operation. -- -- Generalizes "Effectful.Provider".@@ -28,6 +29,7 @@ import Data.Coerce import Data.Functor.Identity import Data.Primitive.PrimArray+import GHC.Stack  import Effectful import Effectful.Dispatch.Static@@ -36,86 +38,95 @@ import Effectful.Internal.Env (Env(..)) import Effectful.Internal.Utils --- | Provide a way to run a handler of multiple @effects@ with a given @input@.+-- | Provide a way to run a handler of multiple @providedEs@ with a given+-- @input@. -- -- /Note:/ @f@ can be used to alter the return type of the handler. If that's -- unnecessary, use 'ProviderList_'.-data ProviderList (effects :: [Effect]) (input :: Type) (f :: Type -> Type) :: Effect+data ProviderList (providedEs :: [Effect]) (input :: Type) (f :: Type -> Type) :: Effect  -- | A restricted variant of 'ProviderList' with unchanged return type of the -- handler.-type ProviderList_ effs input = ProviderList effs input Identity+type ProviderList_ providedEs input = ProviderList providedEs input Identity -type instance DispatchOf (ProviderList effs input f) = Static NoSideEffects+type instance DispatchOf (ProviderList providedEs input f) = Static NoSideEffects -data instance StaticRep (ProviderList effs input f) where+data instance StaticRep (ProviderList providedEs input f) where   ProviderList-    :: KnownEffects effs+    :: KnownEffects providedEs     => !(Env handlerEs)-    -> !(forall r. input -> Eff (effs ++ handlerEs) r -> Eff handlerEs (f r))-    -> StaticRep (ProviderList effs input f)+    -> !(forall r. HasCallStack => input -> Eff (providedEs ++ handlerEs) r -> Eff handlerEs (f r))+    -> StaticRep (ProviderList providedEs input f)  -- | Run the 'ProviderList' effect with a given handler. runProviderList-  :: KnownEffects effs-  => (forall r. input -> Eff (effs ++ es) r -> Eff es (f r))+  :: (HasCallStack, KnownEffects providedEs)+  => (forall r. HasCallStack => input -> Eff (providedEs ++ es) r -> Eff es (f r))   -- ^ The handler.-  -> Eff (ProviderList effs input f : es) a+  -> Eff (ProviderList providedEs input f : es) a   -> Eff es a-runProviderList run m = unsafeEff $ \es0 -> do+runProviderList providerList m = unsafeEff $ \es0 -> do   inlineBracket-    (consEnv (ProviderList es0 run) relinkProviderList es0)+    (consEnv (mkProviderList es0) relinkProviderList es0)     unconsEnv     (\es -> unEff m es)+  where+    -- Corresponds to withFrozenCallStack in provideListWith.+    mkProviderList es =+      ProviderList es (let ?callStack = thawCallStack ?callStack in providerList)  -- | Run the 'Provider' effect with a given handler that doesn't change its -- return type. runProviderList_-  :: KnownEffects effs-  => (forall r. input -> Eff (effs ++ es) r -> Eff es r)+  :: (HasCallStack, KnownEffects providedEs)+  => (forall r. HasCallStack => input -> Eff (providedEs ++ es) r -> Eff es r)   -- ^ The handler.-  -> Eff (ProviderList_ effs input : es) a+  -> Eff (ProviderList_ providedEs input : es) a   -> Eff es a-runProviderList_ run = runProviderList $ \input -> coerce . run input+runProviderList_ providerList = runProviderList $ \input -> coerce . providerList input  -- | Run the handler. provideList-  :: forall effs f es a-   . ProviderList effs () f :> es-  => Eff (effs ++ es) a+  :: forall providedEs f es a+   . (HasCallStack, ProviderList providedEs () f :> es)+  => Eff (providedEs ++ es) a   -> Eff es (f a)-provideList = provideListWith @effs ()+provideList = provideListWith @providedEs ()  -- | Run the handler with unchanged return type. provideList_-  :: forall effs es a-   . ProviderList_ effs () :> es-  => Eff (effs ++ es) a+  :: forall providedEs es a+   . (HasCallStack, ProviderList_ providedEs () :> es)+  => Eff (providedEs ++ es) a   -> Eff es a-provideList_ = provideListWith_ @effs ()+provideList_ = provideListWith_ @providedEs ()  -- | Run the handler with a given input. provideListWith-  :: forall effs input f es a-   . ProviderList effs input f :> es+  :: forall providedEs input f es a+   . (HasCallStack, ProviderList providedEs input f :> es)   => input   -- ^ The input to the handler.-  -> Eff (effs ++ es) a+  -> Eff (providedEs ++ es) a   -> Eff es (f a) provideListWith input action = unsafeEff $ \es -> do-  ProviderList (handlerEs :: Env handlerEs) run <- getEnv @(ProviderList effs input f) es-  (`unEff` handlerEs) . run input . unsafeEff $ \eHandlerEs -> do-    unEff action =<< copyRefs @effs @handlerEs eHandlerEs es+  ProviderList (handlerEs :: Env handlerEs) providerList <- do+    getEnv @(ProviderList providedEs input f) es+  (`unEff` handlerEs)+    -- Corresponds to a thawCallStack in runProviderList.+    . withFrozenCallStack providerList input+    . unsafeEff $ \eHandlerEs -> do+    unEff action =<< copyRefs @providedEs @handlerEs eHandlerEs es  -- | Run the handler that doesn't change its return type with a given input. provideListWith_-  :: forall effs input es a-   . ProviderList_ effs input :> es+  :: forall providedEs input es a+   . (HasCallStack, ProviderList_ providedEs input :> es)   => input   -- ^ The input to the handler.-  -> Eff (effs ++ es) a+  -> Eff (providedEs ++ es) a   -> Eff es a-provideListWith_ input = adapt . provideListWith @effs input+provideListWith_ input = adapt . provideListWith @providedEs input   where     adapt :: Eff es (Identity a) -> Eff es a     adapt = coerce@@ -129,18 +140,18 @@   pure $ ProviderList newHandlerEs run  copyRefs-  :: forall effs handlerEs es-   . KnownEffects effs-  => Env (effs ++ handlerEs)+  :: forall providedEs handlerEs es+   . (HasCallStack, KnownEffects providedEs)+  => Env (providedEs ++ handlerEs)   -> Env es-  -> IO (Env (effs ++ es))+  -> IO (Env (providedEs ++ es)) copyRefs (Env hoffset hrefs hstorage) (Env offset refs0 storage) = do   when (hstorage /= storage) $ do     error "storages do not match"-  let size = sizeofPrimArray refs0 - offset-      effsSize = 2 * knownEffectsLength @effs-  mrefs <- newPrimArray (size + effsSize)-  copyPrimArray mrefs 0 hrefs hoffset effsSize-  copyPrimArray mrefs effsSize refs0 offset size+  let providedEsSize = knownEffectsLength @providedEs+      esSize = sizeofPrimArray refs0 - offset+  mrefs <- newPrimArray (providedEsSize + esSize)+  copyPrimArray mrefs 0 hrefs hoffset providedEsSize+  copyPrimArray mrefs providedEsSize refs0 offset esSize   refs <- unsafeFreezePrimArray mrefs   pure $ Env 0 refs storage
src/Effectful/Reader/Dynamic.hs view
@@ -30,7 +30,8 @@ -- | Run the 'Reader' effect with the given initial environment (via -- "Effectful.Reader.Static"). runReader-  :: r -- ^ The initial environment.+  :: HasCallStack+  => r -- ^ The initial environment.   -> Eff (Reader r : es) a   -> Eff es a runReader r = reinterpret (R.runReader r) $ \env -> \case@@ -41,7 +42,8 @@ -- -- @since 1.1.0.0 withReader-  :: (r1 -> r2)+  :: HasCallStack+  => (r1 -> r2)   -- ^ The function to modify the environment.   -> Eff (Reader r2 : es) a   -- ^ Computation to run in the modified environment.
src/Effectful/Reader/Static.hs view
@@ -13,19 +13,22 @@   , local   ) where +import Data.Kind+ import Effectful import Effectful.Dispatch.Static  -- | Provide access to a strict (WHNF), thread local, read only value of type -- @r@.-data Reader r :: Effect+data Reader (r :: Type) :: Effect  type instance DispatchOf (Reader r) = Static NoSideEffects newtype instance StaticRep (Reader r) = Reader r  -- | Run a 'Reader' effect with the given initial environment. runReader-  :: r -- ^ The initial environment.+  :: HasCallStack+  => r -- ^ The initial environment.   -> Eff (Reader r : es) a   -> Eff es a runReader r = evalStaticRep (Reader r)@@ -34,7 +37,8 @@ -- -- @since 1.1.0.0 withReader-  :: (r1 -> r2)+  :: HasCallStack+  => (r1 -> r2)   -- ^ The function to modify the environment.   -> Eff (Reader r2 : es) a   -- ^ Computation to run in the modified environment.@@ -44,7 +48,7 @@   raise $ runReader (f r) m  -- | Fetch the value of the environment.-ask :: Reader r :> es => Eff es r+ask :: (HasCallStack, Reader r :> es) => Eff es r ask = do   Reader r <- getStaticRep   pure r@@ -53,7 +57,7 @@ -- -- @'asks' f ≡ f '<$>' 'ask'@ asks-  :: Reader r :> es+  :: (HasCallStack, Reader r :> es)   => (r -> a) -- ^ The function to apply to the environment.   -> Eff es a asks f = f <$> ask@@ -63,7 +67,7 @@ -- @'runReader' r ('local' f m) ≡ 'runReader' (f r) m@ -- local-  :: Reader r :> es+  :: (HasCallStack, Reader r :> es)   => (r -> r) -- ^ The function to modify the environment.   -> Eff es a   -> Eff es a
src/Effectful/State/Dynamic.hs view
@@ -48,24 +48,20 @@  -- | Run the 'State' effect with the given initial state and return the final -- value along with the final state (via "Effectful.State.Static.Local").-runStateLocal :: s -> Eff (State s : es) a -> Eff es (a, s)+runStateLocal :: HasCallStack => s -> Eff (State s : es) a -> Eff es (a, s) runStateLocal s0 = reinterpret (L.runState s0) localState  -- | Run the 'State' effect with the given initial state and return the final -- value, discarding the final state (via "Effectful.State.Static.Local").-evalStateLocal :: s -> Eff (State s : es) a -> Eff es a+evalStateLocal :: HasCallStack => s -> Eff (State s : es) a -> Eff es a evalStateLocal s0 = reinterpret (L.evalState s0) localState  -- | Run the 'State' effect with the given initial state and return the final -- state, discarding the final value (via "Effectful.State.Static.Local").-execStateLocal :: s -> Eff (State s : es) a -> Eff es s+execStateLocal :: HasCallStack => s -> Eff (State s : es) a -> Eff es s execStateLocal s0 = reinterpret (L.execState s0) localState -localState-  :: L.State s :> es-  => LocalEnv localEs es-  -> State s (Eff localEs) a-  -> Eff es a+localState :: L.State s :> es => EffectHandler (State s) es localState env = \case   Get      -> L.get   Put s    -> L.put s@@ -77,24 +73,20 @@  -- | Run the 'State' effect with the given initial state and return the final -- value along with the final state (via "Effectful.State.Static.Shared").-runStateShared :: s -> Eff (State s : es) a -> Eff es (a, s)+runStateShared :: HasCallStack => s -> Eff (State s : es) a -> Eff es (a, s) runStateShared s0 = reinterpret (S.runState s0) sharedState  -- | Run the 'State' effect with the given initial state and return the final -- value, discarding the final state (via "Effectful.State.Static.Shared").-evalStateShared :: s -> Eff (State s : es) a -> Eff es a+evalStateShared :: HasCallStack => s -> Eff (State s : es) a -> Eff es a evalStateShared s0 = reinterpret (S.evalState s0) sharedState  -- | Run the 'State' effect with the given initial state and return the final -- state, discarding the final value (via "Effectful.State.Static.Shared").-execStateShared :: s -> Eff (State s : es) a -> Eff es s+execStateShared :: HasCallStack => s -> Eff (State s : es) a -> Eff es s execStateShared s0 = reinterpret (S.execState s0) sharedState -sharedState-  :: S.State s :> es-  => LocalEnv localEs es-  -> State s (Eff localEs) a-  -> Eff es a+sharedState :: S.State s :> es => EffectHandler (State s) es sharedState env = \case   Get      -> S.get   Put s    -> S.put s
src/Effectful/State/Static/Local.hs view
@@ -7,7 +7,7 @@ -- the @transformers@ library, the 'State' effect doesn't discard state updates -- when an exception is received: ----- >>> import qualified Control.Monad.Trans.State.Strict as S+-- >>> import Control.Monad.Trans.State.Strict qualified as S -- -- >>> :{ --   (`S.execStateT` "Hi") . handle (\(_::ErrorCall) -> pure ()) $ do@@ -41,11 +41,13 @@   , modifyM   ) where +import Data.Kind+ import Effectful import Effectful.Dispatch.Static  -- | Provide access to a strict (WHNF), thread local, mutable value of type @s@.-data State s :: Effect+data State (s :: Type) :: Effect  type instance DispatchOf (State s) = Static NoSideEffects newtype instance StaticRep (State s) = State s@@ -53,7 +55,8 @@ -- | Run the 'State' effect with the given initial state and return the final -- value along with the final state. runState-  :: s -- ^ The initial state.+  :: HasCallStack+  => s -- ^ The initial state.   -> Eff (State s : es) a   -> Eff es (a, s) runState s0 m = do@@ -63,7 +66,8 @@ -- | Run the 'State' effect with the given initial state and return the final -- value, discarding the final state. evalState-  :: s -- ^ The initial state.+  :: HasCallStack+  => s -- ^ The initial state.   -> Eff (State s : es) a   -> Eff es a evalState s = evalStaticRep (State s)@@ -71,7 +75,8 @@ -- | Run the 'State' effect with the given initial state and return the final -- state, discarding the final value. execState-  :: s -- ^ The initial state.+  :: HasCallStack+  => s -- ^ The initial state.   -> Eff (State s : es) a   -> Eff es s execState s0 m = do@@ -79,7 +84,7 @@   pure s  -- | Fetch the current value of the state.-get :: State s :> es => Eff es s+get :: (HasCallStack, State s :> es) => Eff es s get = do   State s <- getStaticRep   pure s@@ -88,18 +93,18 @@ -- -- @'gets' f ≡ f '<$>' 'get'@ gets-  :: State s :> es+  :: (HasCallStack, State s :> es)   => (s -> a) -- ^ The function to apply to the state.   -> Eff es a gets f = f <$> get  -- | Set the current state to the given value.-put :: State s :> es => s -> Eff es ()+put :: (HasCallStack, State s :> es) => s -> Eff es () put s = putStaticRep (State s)  -- | Apply the function to the current state and return a value. state-  :: State s :> es+  :: (HasCallStack, State s :> es)   => (s -> (a, s)) -- ^ The function to modify the state.   -> Eff es a state f = stateStaticRep $ \(State s0) -> let (a, s) = f s0 in (a, State s)@@ -108,14 +113,14 @@ -- -- @'modify' f ≡ 'state' (\\s -> ((), f s))@ modify-  :: State s :> es+  :: (HasCallStack, State s :> es)   => (s -> s) -- ^ The function to modify the state.   -> Eff es () modify f = state $ \s -> ((), f s)  -- | Apply the monadic function to the current state and return a value. stateM-  :: State s :> es+  :: (HasCallStack, State s :> es)   => (s -> Eff es (a, s)) -- ^ The function to modify the state.   -> Eff es a stateM f = stateStaticRepM $ \(State s0) -> do@@ -126,11 +131,10 @@ -- -- @'modifyM' f ≡ 'stateM' (\\s -> ((), ) '<$>' f s)@ modifyM-  :: State s :> es+  :: (HasCallStack, State s :> es)   => (s -> Eff es s) -- ^ The monadic function to modify the state.   -> Eff es () modifyM f = stateM (\s -> ((), ) <$> f s)  -- $setup--- >>> import Control.Exception (ErrorCall)--- >>> import Control.Monad.Catch+-- >>> import Effectful.Exception
src/Effectful/State/Static/Shared.hs view
@@ -7,7 +7,7 @@ -- the @transformers@ library, the 'State' effect doesn't discard state updates -- when an exception is received: ----- >>> import qualified Control.Monad.Trans.State.Strict as S+-- >>> import Control.Monad.Trans.State.Strict qualified as S -- -- >>> :{ --   (`S.execStateT` "Hi") . handle (\(_::ErrorCall) -> pure ()) $ do@@ -45,22 +45,22 @@   , modifyM   ) where -import Control.Concurrent.MVar+import Control.Concurrent.MVar.Strict+import Data.Kind  import Effectful import Effectful.Dispatch.Static import Effectful.Dispatch.Static.Primitive-import Effectful.Internal.Utils  -- | Provide access to a strict (WHNF), shared, mutable value of type @s@.-data State s :: Effect+data State (s :: Type) :: Effect  type instance DispatchOf (State s) = Static NoSideEffects newtype instance StaticRep (State s) = State (MVar' s)  -- | Run the 'State' effect with the given initial state and return the final -- value along with the final state.-runState :: s -> Eff (State s : es) a -> Eff es (a, s)+runState :: HasCallStack => s -> Eff (State s : es) a -> Eff es (a, s) runState s m = do   v <- unsafeEff_ $ newMVar' s   a <- evalStaticRep (State v) m@@ -68,44 +68,40 @@  -- | Run the 'State' effect with the given initial state and return the final -- value, discarding the final state.-evalState :: s -> Eff (State s : es) a -> Eff es a+evalState :: HasCallStack => s -> Eff (State s : es) a -> Eff es a evalState s m = do   v <- unsafeEff_ $ newMVar' s   evalStaticRep (State v) m  -- | Run the 'State' effect with the given initial state and return the final -- state, discarding the final value.-execState :: s -> Eff (State s : es) a -> Eff es s+execState :: HasCallStack => s -> Eff (State s : es) a -> Eff es s execState s m = do   v <- unsafeEff_ $ newMVar' s   _ <- evalStaticRep (State v) m   unsafeEff_ $ readMVar' v --- | Run the 'State' effect with the given initial state 'MVar' and return the+-- | Run the 'State' effect with the given initial state 'MVar'' and return the -- final value along with the final state.-runStateMVar :: MVar s -> Eff (State s : es) a -> Eff es (a, s)+runStateMVar :: HasCallStack => MVar' s -> Eff (State s : es) a -> Eff es (a, s) runStateMVar v m = do-  v' <- unsafeEff_ $ toMVar' v-  a <- evalStaticRep (State v') m-  (a, ) <$> unsafeEff_ (readMVar v)+  a <- evalStaticRep (State v) m+  (a, ) <$> unsafeEff_ (readMVar' v) --- | Run the 'State' effect with the given initial state 'MVar' and return the+-- | Run the 'State' effect with the given initial state 'MVar'' and return the -- final value, discarding the final state.-evalStateMVar :: MVar s -> Eff (State s : es) a -> Eff es a-evalStateMVar v m = do-  v' <- unsafeEff_ $ toMVar' v-  evalStaticRep (State v') m+evalStateMVar :: HasCallStack => MVar' s -> Eff (State s : es) a -> Eff es a+evalStateMVar v = evalStaticRep (State v) --- | Run the 'State' effect with the given initial state 'MVar' and return the+-- | Run the 'State' effect with the given initial state 'MVar'' and return the -- final state, discarding the final value.-execStateMVar :: MVar s -> Eff (State s : es) a -> Eff es s+execStateMVar :: HasCallStack => MVar' s -> Eff (State s : es) a -> Eff es s execStateMVar v m = do-  v' <- unsafeEff_ $ toMVar' v-  _ <- evalStaticRep (State v') m-  unsafeEff_ $ readMVar v+  _ <- evalStaticRep (State v) m+  unsafeEff_ $ readMVar' v  -- | Fetch the current value of the state.-get :: State s :> es => Eff es s+get :: (HasCallStack, State s :> es) => Eff es s get = unsafeEff $ \es -> do   State v <- getEnv es   readMVar' v@@ -113,19 +109,19 @@ -- | Get a function of the current state. -- -- @'gets' f ≡ f '<$>' 'get'@-gets :: State s :> es => (s -> a) -> Eff es a+gets :: (HasCallStack, State s :> es) => (s -> a) -> Eff es a gets f = f <$> get  -- | Set the current state to the given value.-put :: State s :> es => s -> Eff es ()+put :: (HasCallStack, State s :> es) => s -> Eff es () put s = unsafeEff $ \es -> do   State v <- getEnv es-  modifyMVar_' v $ \_ -> pure s+  modifyMVar'_ v $ \_ -> pure s  -- | Apply the function to the current state and return a value. -- -- /Note:/ this function gets an exclusive access to the state for its duration.-state :: State s :> es => (s -> (a, s)) -> Eff es a+state :: (HasCallStack, State s :> es) => (s -> (a, s)) -> Eff es a state f = unsafeEff $ \es -> do   State v <- getEnv es   modifyMVar' v $ \s0 -> let (a, s) = f s0 in pure (s, a)@@ -135,13 +131,13 @@ -- @'modify' f ≡ 'state' (\\s -> ((), f s))@ -- -- /Note:/ this function gets an exclusive access to the state for its duration.-modify :: State s :> es => (s -> s) -> Eff es ()+modify :: (HasCallStack, State s :> es) => (s -> s) -> Eff es () modify f = state (\s -> ((), f s))  -- | Apply the monadic function to the current state and return a value. -- -- /Note:/ this function gets an exclusive access to the state for its duration.-stateM :: State s :> es => (s -> Eff es (a, s)) -> Eff es a+stateM :: (HasCallStack, State s :> es) => (s -> Eff es (a, s)) -> Eff es a stateM f = unsafeEff $ \es -> do   State v <- getEnv es   modifyMVar' v $ \s0 -> do@@ -153,9 +149,8 @@ -- @'modifyM' f ≡ 'stateM' (\\s -> ((), ) '<$>' f s)@ -- -- /Note:/ this function gets an exclusive access to the state for its duration.-modifyM :: State s :> es => (s -> Eff es s) -> Eff es ()+modifyM :: (HasCallStack, State s :> es) => (s -> Eff es s) -> Eff es () modifyM f = stateM (\s -> ((), ) <$> f s)  -- $setup--- >>> import Control.Exception (ErrorCall)--- >>> import Control.Monad.Catch+-- >>> import Effectful.Exception
src/Effectful/Writer/Dynamic.hs view
@@ -40,19 +40,15 @@  -- | Run the 'Writer' effect and return the final value along with the final -- output (via "Effectful.Writer.Static.Local").-runWriterLocal :: Monoid w => Eff (Writer w : es) a -> Eff es (a, w)+runWriterLocal :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es (a, w) runWriterLocal = reinterpret L.runWriter localWriter  -- | Run a 'Writer' effect and return the final output, discarding the final -- value (via "Effectful.Writer.Static.Local").-execWriterLocal :: Monoid w => Eff (Writer w : es) a -> Eff es w+execWriterLocal :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es w execWriterLocal = reinterpret L.execWriter localWriter -localWriter-  :: (L.Writer w :> es, Monoid w)-  => LocalEnv localEs es-  -> Writer w (Eff localEs) a-  -> Eff es a+localWriter :: (L.Writer w :> es, Monoid w) => EffectHandler (Writer w) es localWriter env = \case   Tell w   -> L.tell w   Listen m -> localSeqUnlift env $ \unlift -> L.listen (unlift m)@@ -62,19 +58,15 @@  -- | Run the 'Writer' effect and return the final value along with the final -- output (via "Effectful.Writer.Static.Shared").-runWriterShared :: Monoid w => Eff (Writer w : es) a -> Eff es (a, w)+runWriterShared :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es (a, w) runWriterShared = reinterpret S.runWriter sharedWriter  -- | Run the 'Writer' effect and return the final output, discarding the final -- value (via "Effectful.Writer.Static.Shared").-execWriterShared :: Monoid w => Eff (Writer w : es) a -> Eff es w+execWriterShared :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es w execWriterShared = reinterpret S.execWriter sharedWriter -sharedWriter-  :: (S.Writer w :> es, Monoid w)-  => LocalEnv localEs es-  -> Writer w (Eff localEs) a-  -> Eff es a+sharedWriter :: (S.Writer w :> es, Monoid w) => EffectHandler (Writer w) es sharedWriter env = \case   Tell w    -> S.tell w   Listen m  -> localSeqUnlift env $ \unlift -> S.listen (unlift m)
src/Effectful/Writer/Static/Local.hs view
@@ -28,6 +28,7 @@   ) where  import Control.Exception (onException, mask)+import Data.Kind  import Effectful import Effectful.Dispatch.Static@@ -35,27 +36,27 @@  -- | Provide access to a strict (WHNF), thread local, write only value of type -- @w@.-data Writer w :: Effect+data Writer (w :: Type) :: Effect  type instance DispatchOf (Writer w) = Static NoSideEffects newtype instance StaticRep (Writer w) = Writer w  -- | Run a 'Writer' effect and return the final value along with the final -- output.-runWriter :: Monoid w => Eff (Writer w : es) a -> Eff es (a, w)+runWriter :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es (a, w) runWriter m = do   (a, Writer w) <- runStaticRep (Writer mempty) m   pure (a, w)  -- | Run a 'Writer' effect and return the final output, discarding the final -- value.-execWriter :: Monoid w => Eff (Writer w : es) a -> Eff es w+execWriter :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es w execWriter m = do   Writer w <- execStaticRep (Writer mempty) m   pure w  -- | Append the given output to the overall output of the 'Writer'.-tell :: (Writer w :> es, Monoid w) => w -> Eff es ()+tell :: (HasCallStack, Writer w :> es, Monoid w) => w -> Eff es () tell w = stateStaticRep $ \(Writer w0) -> ((), Writer (w0 <> w))  -- | Execute an action and append its output to the overall output of the@@ -75,26 +76,30 @@ --         error "oops" -- :} -- "Hi there!"-listen :: (Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w)+listen :: (HasCallStack, Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w) listen m = unsafeEff $ \es -> mask $ \unmask -> do-  w0 <- stateEnv es $ \(Writer w) -> pure (w, Writer mempty)+  w0 <- stateEnv es $ \(Writer w) -> (w, Writer mempty)   a <- unmask (unEff m es) `onException` merge es w0   (a, ) <$> merge es w0   where     merge es w0 =       -- If an exception is thrown, restore w0 and keep parts of w1.-      stateEnv es $ \(Writer w1) -> pure (w1, Writer (w0 <> w1))+      stateEnv es $ \(Writer w1) -> (w1, Writer (w0 <> w1))  -- | Execute an action and append its output to the overall output of the -- 'Writer', then return the final value along with a function of the recorded -- output. -- -- @'listens' f m ≡ 'Data.Bifunctor.second' f '<$>' 'listen' m@-listens :: (Writer w :> es, Monoid w) => (w -> b) -> Eff es a -> Eff es (a, b)+listens+  :: (HasCallStack, Writer w :> es, Monoid w)+  => (w -> b)+  -> Eff es a+  -> Eff es (a, b) listens f m = do   (a, w) <- listen m   pure (a, f w)  -- $setup -- >>> import Control.Exception (ErrorCall)--- >>> import Control.Monad.Catch+-- >>> import Effectful.Exception
src/Effectful/Writer/Static/Shared.hs view
@@ -27,22 +27,23 @@   , listens   ) where +import Control.Concurrent.MVar.Strict import Control.Exception (onException, uninterruptibleMask)+import Data.Kind  import Effectful import Effectful.Dispatch.Static import Effectful.Dispatch.Static.Primitive-import Effectful.Internal.Utils  -- | Provide access to a strict (WHNF), shared, write only value of type @w@.-data Writer w :: Effect+data Writer (w :: Type) :: Effect  type instance DispatchOf (Writer w) = Static NoSideEffects newtype instance StaticRep (Writer w) = Writer (MVar' w)  -- | Run a 'Writer' effect and return the final value along with the final -- output.-runWriter :: Monoid w => Eff (Writer w : es) a -> Eff es (a, w)+runWriter :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es (a, w) runWriter m = do   v <- unsafeEff_ $ newMVar' mempty   a <- evalStaticRep (Writer v) m@@ -50,17 +51,17 @@  -- | Run a 'Writer' effect and return the final output, discarding the final -- value.-execWriter :: Monoid w => Eff (Writer w : es) a -> Eff es w+execWriter :: (HasCallStack, Monoid w) => Eff (Writer w : es) a -> Eff es w execWriter m = do   v <- unsafeEff_ $ newMVar' mempty   _ <- evalStaticRep (Writer v) m   unsafeEff_ $ readMVar' v  -- | Append the given output to the overall output of the 'Writer'.-tell :: (Writer w :> es, Monoid w) => w -> Eff es ()+tell :: (HasCallStack, Writer w :> es, Monoid w) => w -> Eff es () tell w1 = unsafeEff $ \es -> do   Writer v <- getEnv es-  modifyMVar_' v $ \w0 -> let w = w0 <> w1 in pure w+  modifyMVar'_ v $ \w0 -> let w = w0 <> w1 in pure w  -- | Execute an action and append its output to the overall output of the -- 'Writer'.@@ -79,7 +80,7 @@ --         error "oops" -- :} -- "Hi there!"-listen :: (Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w)+listen :: (HasCallStack, Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w) listen m = unsafeEff $ \es -> do   -- The mask is uninterruptible because modifyMVar_ v0 in the merge function   -- might block and if an async exception is received while waiting, w1 will be@@ -87,7 +88,7 @@   uninterruptibleMask $ \unmask -> do     v1 <- newMVar' mempty     -- Replace thread local MVar with a fresh one for isolated listening.-    v0 <- stateEnv es $ \(Writer v) -> pure (v, Writer v1)+    v0 <- stateEnv es $ \(Writer v) -> (v, Writer v1)     a <- unmask (unEff m es) `onException` merge es v0 v1     (a, ) <$> merge es v0 v1   where@@ -96,7 +97,7 @@     merge es v0 v1 = do       putEnv es $ Writer v0       w1 <- readMVar' v1-      modifyMVar_' v0 $ \w0 -> let w = w0 <> w1 in pure w+      modifyMVar'_ v0 $ \w0 -> let w = w0 <> w1 in pure w       pure w1  -- | Execute an action and append its output to the overall output of the@@ -104,11 +105,15 @@ -- output. -- -- @'listens' f m ≡ 'Data.Bifunctor.second' f '<$>' 'listen' m@-listens :: (Writer w :> es, Monoid w) => (w -> b) -> Eff es a -> Eff es (a, b)+listens+  :: (HasCallStack, Writer w :> es, Monoid w)+  => (w -> b)+  -> Eff es a+  -> Eff es (a, b) listens f m = do   (a, w) <- listen m   pure (a, f w)  -- $setup -- >>> import Control.Exception (ErrorCall)--- >>> import Control.Monad.Catch+-- >>> import Effectful.Exception