{-# LANGUAGE AllowAmbiguousTypes #-}
-- | Convenience functions for the 'Labeled' 'ReturnWith' effect.
--
-- @since 2.7.0.0
module Effectful.Labeled.ReturnWith
  ( -- * Effect
    ReturnWith(..)

    -- ** Handlers
  , runReturnWith

    -- ** Operations
  , returnWith

    -- * Re-exports
  , Labeled(..)
  ) where

import GHC.Stack (withFrozenCallStack)

import Effectful
import Effectful.Dispatch.Dynamic
import Effectful.Labeled
import Effectful.ReturnWith.Dynamic (ReturnWith(..))
import Effectful.ReturnWith.Dynamic qualified as R

-- | Run a computation that can return early with a value of type @r@ (via
-- "Effectful.ReturnWith.Static").
runReturnWith
  :: forall label r es
   . HasCallStack
  => Eff (Labeled label (ReturnWith r) : es) r
  -> Eff es r
runReturnWith :: forall {k} (label :: k) r (es :: [(Type -> Type) -> Type -> Type]).
HasCallStack =>
Eff (Labeled label (ReturnWith r) : es) r -> Eff es r
runReturnWith = forall (label :: k) (e :: (Type -> Type) -> Type -> Type)
       (es :: [(Type -> Type) -> Type -> Type]) a b.
HasCallStack =>
(Eff (e : es) a -> Eff es b)
-> Eff (Labeled label e : es) a -> Eff es b
forall {k} (label :: k) (e :: (Type -> Type) -> Type -> Type)
       (es :: [(Type -> Type) -> Type -> Type]) a b.
HasCallStack =>
(Eff (e : es) a -> Eff es b)
-> Eff (Labeled label e : es) a -> Eff es b
runLabeled @label Eff (ReturnWith r : es) r -> Eff es r
forall r (es :: [(Type -> Type) -> Type -> Type]).
HasCallStack =>
Eff (ReturnWith r : es) r -> Eff es r
R.runReturnWith

-- | Return early with the given value.
returnWith
  :: forall label r es a
   . (HasCallStack, Labeled label (ReturnWith r) :> es)
  => r
  -- ^ The value.
  -> Eff es a
returnWith :: forall {k} (label :: k) r (es :: [(Type -> Type) -> Type -> Type])
       a.
(HasCallStack, Labeled label (ReturnWith r) :> es) =>
r -> Eff es a
returnWith = (HasCallStack =>
 Labeled label (ReturnWith r) (Eff es) a -> Eff es a)
-> Labeled label (ReturnWith r) (Eff es) a -> Eff es a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack HasCallStack => Labeled label (ReturnWith r) (Eff es) a -> Eff es a
Labeled label (ReturnWith r) (Eff es) a -> Eff es a
forall (e :: (Type -> Type) -> Type -> Type)
       (es :: [(Type -> Type) -> Type -> Type]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Labeled label (ReturnWith r) (Eff es) a -> Eff es a)
-> (r -> Labeled label (ReturnWith r) (Eff es) a) -> r -> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (label :: k) (e :: (Type -> Type) -> Type -> Type)
       (a :: Type -> Type) b.
e a b -> Labeled label e a b
forall {k} (label :: k) (e :: (Type -> Type) -> Type -> Type)
       (a :: Type -> Type) b.
e a b -> Labeled label e a b
Labeled @label (ReturnWith r (Eff es) a
 -> Labeled label (ReturnWith r) (Eff es) a)
-> (r -> ReturnWith r (Eff es) a)
-> r
-> Labeled label (ReturnWith r) (Eff es) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r -> ReturnWith r (Eff es) a
forall r (a :: Type -> Type) b. r -> ReturnWith r a b
ReturnWith