module Control.Effects.Early
( module Control.Effects, Early
, earlyReturn, handleEarly, onlyDo, ifNothingEarlyReturn, ifNothingDo
, ifLeftEarlyReturn, ifLeftDo ) where
import Import
import Control.Effects
newtype Early a = Early { getEarlyReturn :: a }
type instance EffectMsg (Early a) = a
type instance EffectRes (Early a) = Void
instance (Monad m, a ~ b) => MonadEffect (Early a) (ExceptT (Early b) m) where
effect _ = throwE . Early
earlyReturn :: forall a b m. MonadEffect (Early a) m => a -> m b
earlyReturn = fmap (getEarlyReturn . absurd) . effect (Proxy :: Proxy (Early a))
handleEarly :: Monad m => ExceptT (Early a) m a -> m a
handleEarly = fmap (either getEarlyReturn id)
. runExceptT
onlyDo :: MonadEffect (Early a) m => m a -> m b
onlyDo m = m >>= earlyReturn
ifNothingEarlyReturn :: MonadEffect (Early a) m => a -> Maybe b -> m b
ifNothingEarlyReturn a = maybe (earlyReturn a) return
ifNothingDo :: MonadEffect (Early a) m => m a -> Maybe b -> m b
ifNothingDo m = maybe (onlyDo m) return
ifLeftEarlyReturn :: MonadEffect (Early c) m => (a -> c) -> Either a b -> m b
ifLeftEarlyReturn f = either (earlyReturn . f) return
ifLeftDo :: MonadEffect (Early c) m => (a -> m c) -> Either a b -> m b
ifLeftDo f = either (onlyDo . f) return