{-# LANGUAGE TemplateHaskell #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Control.Effect.Embed
-- Copyright   :  (c) Michael Szvetits, 2020
-- License     :  BSD3 (see the file LICENSE)
-- Maintainer  :  typedbyte@qualified.name
-- Stability   :  stable
-- Portability :  portable
--
-- The embed effect for integrating arbitrary monads into the effect system.
-----------------------------------------------------------------------------
module Control.Effect.Embed
  ( -- * Tagged Embed Effect
    Embed'(..)
    -- * Untagged Embed Effect
    -- | If you don't require disambiguation of multiple embed effects
    -- (i.e., you only have one embed effect in your monadic context),
    -- it is recommended to always use the untagged embed effect.
  , Embed
  , embed
    -- * Interpretations
    -- ** Via Transformation
  , Transformation
  , runEmbed'
  , runEmbed
    -- ** Via Finalization
  , Finalization
  , runFinal'
  , runFinal
    -- * Tagging and Untagging
    -- | Conversion functions between the tagged and untagged embed effect,
    -- usually used in combination with type applications, like:
    --
    -- @
    --     'tagEmbed'' \@\"newTag\" program
    --     'retagEmbed'' \@\"oldTag\" \@\"newTag\" program
    --     'untagEmbed'' \@\"erasedTag\" program
    -- @
    -- 
  , tagEmbed'
  , retagEmbed'
  , untagEmbed'
  ) where

-- base
import Data.Coerce           (coerce)
import Data.Functor.Identity (Identity)

-- transformers
import Control.Monad.Trans.Reader (ReaderT(ReaderT), runReaderT)

import Control.Effect.Machinery hiding (embed)

-- | An effect that integrates a monad @n@ into the computation @m@.
--
-- @since 0.3.0.0
class Monad m => Embed' tag n m | tag m -> n where
  -- | Monadic actions in @n@ can be lifted into @m@ via 'embed'.
  --
  -- 'embed' is like 'liftIO', but not limited to 'IO'. In fact, 'liftIO' can
  -- be realized using 'embed' by specializing @n@ to @IO@.
  --
  -- @since 0.3.0.0
  embed' :: n a -> m a

makeTaggedEffect ''Embed'

instance Embed' tag IO IO where
  embed' :: IO a -> IO a
embed' = IO a -> IO a
forall a. a -> a
id
  {-# INLINE embed' #-}

instance Embed' tag Maybe Maybe where
  embed' :: Maybe a -> Maybe a
embed' = Maybe a -> Maybe a
forall a. a -> a
id
  {-# INLINE embed' #-}

instance Embed' tag [] [] where
  embed' :: [a] -> [a]
embed' = [a] -> [a]
forall a. a -> a
id
  {-# INLINE embed' #-}

instance Embed' tag Identity Identity where
  embed' :: Identity a -> Identity a
embed' = Identity a -> Identity a
forall a. a -> a
id
  {-# INLINE embed' #-}

newtype F n t = F (forall b. n b -> t b)

-- | The transformation interpreter of the embed effect. This type implements the
-- 'Embed' type class by transforming the integrated monad @n@ into another
-- integrated monad @t@ via natural transformation.
--
-- When interpreting the effect, you usually don\'t interact with this type directly,
-- but instead use one of its corresponding interpretation functions.
newtype Transformation n t m a =
  Transformation { Transformation n t m a -> ReaderT (F n t) m a
runTransformation :: ReaderT (F n t) m a }
    deriving (Functor (Transformation n t m)
a -> Transformation n t m a
Functor (Transformation n t m)
-> (forall a. a -> Transformation n t m a)
-> (forall a b.
    Transformation n t m (a -> b)
    -> Transformation n t m a -> Transformation n t m b)
-> (forall a b c.
    (a -> b -> c)
    -> Transformation n t m a
    -> Transformation n t m b
    -> Transformation n t m c)
-> (forall a b.
    Transformation n t m a
    -> Transformation n t m b -> Transformation n t m b)
-> (forall a b.
    Transformation n t m a
    -> Transformation n t m b -> Transformation n t m a)
-> Applicative (Transformation n t m)
Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
Transformation n t m a
-> Transformation n t m b -> Transformation n t m a
Transformation n t m (a -> b)
-> Transformation n t m a -> Transformation n t m b
(a -> b -> c)
-> Transformation n t m a
-> Transformation n t m b
-> Transformation n t m c
forall a. a -> Transformation n t m a
forall a b.
Transformation n t m a
-> Transformation n t m b -> Transformation n t m a
forall a b.
Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
forall a b.
Transformation n t m (a -> b)
-> Transformation n t m a -> Transformation n t m b
forall a b c.
(a -> b -> c)
-> Transformation n t m a
-> Transformation n t m b
-> Transformation n t m c
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *).
Applicative m =>
Functor (Transformation n t m)
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Applicative m =>
a -> Transformation n t m a
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Applicative m =>
Transformation n t m a
-> Transformation n t m b -> Transformation n t m a
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Applicative m =>
Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Applicative m =>
Transformation n t m (a -> b)
-> Transformation n t m a -> Transformation n t m b
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> Transformation n t m a
-> Transformation n t m b
-> Transformation n t m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: Transformation n t m a
-> Transformation n t m b -> Transformation n t m a
$c<* :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Applicative m =>
Transformation n t m a
-> Transformation n t m b -> Transformation n t m a
*> :: Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
$c*> :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Applicative m =>
Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
liftA2 :: (a -> b -> c)
-> Transformation n t m a
-> Transformation n t m b
-> Transformation n t m c
$cliftA2 :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> Transformation n t m a
-> Transformation n t m b
-> Transformation n t m c
<*> :: Transformation n t m (a -> b)
-> Transformation n t m a -> Transformation n t m b
$c<*> :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Applicative m =>
Transformation n t m (a -> b)
-> Transformation n t m a -> Transformation n t m b
pure :: a -> Transformation n t m a
$cpure :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Applicative m =>
a -> Transformation n t m a
$cp1Applicative :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *).
Applicative m =>
Functor (Transformation n t m)
Applicative, a -> Transformation n t m b -> Transformation n t m a
(a -> b) -> Transformation n t m a -> Transformation n t m b
(forall a b.
 (a -> b) -> Transformation n t m a -> Transformation n t m b)
-> (forall a b.
    a -> Transformation n t m b -> Transformation n t m a)
-> Functor (Transformation n t m)
forall a b. a -> Transformation n t m b -> Transformation n t m a
forall a b.
(a -> b) -> Transformation n t m a -> Transformation n t m b
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Functor m =>
a -> Transformation n t m b -> Transformation n t m a
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Functor m =>
(a -> b) -> Transformation n t m a -> Transformation n t m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Transformation n t m b -> Transformation n t m a
$c<$ :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Functor m =>
a -> Transformation n t m b -> Transformation n t m a
fmap :: (a -> b) -> Transformation n t m a -> Transformation n t m b
$cfmap :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Functor m =>
(a -> b) -> Transformation n t m a -> Transformation n t m b
Functor, Applicative (Transformation n t m)
a -> Transformation n t m a
Applicative (Transformation n t m)
-> (forall a b.
    Transformation n t m a
    -> (a -> Transformation n t m b) -> Transformation n t m b)
-> (forall a b.
    Transformation n t m a
    -> Transformation n t m b -> Transformation n t m b)
-> (forall a. a -> Transformation n t m a)
-> Monad (Transformation n t m)
Transformation n t m a
-> (a -> Transformation n t m b) -> Transformation n t m b
Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
forall a. a -> Transformation n t m a
forall a b.
Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
forall a b.
Transformation n t m a
-> (a -> Transformation n t m b) -> Transformation n t m b
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *).
Monad m =>
Applicative (Transformation n t m)
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Monad m =>
a -> Transformation n t m a
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Monad m =>
Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Monad m =>
Transformation n t m a
-> (a -> Transformation n t m b) -> Transformation n t m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> Transformation n t m a
$creturn :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Monad m =>
a -> Transformation n t m a
>> :: Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
$c>> :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Monad m =>
Transformation n t m a
-> Transformation n t m b -> Transformation n t m b
>>= :: Transformation n t m a
-> (a -> Transformation n t m b) -> Transformation n t m b
$c>>= :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a b.
Monad m =>
Transformation n t m a
-> (a -> Transformation n t m b) -> Transformation n t m b
$cp1Monad :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *).
Monad m =>
Applicative (Transformation n t m)
Monad, Monad (Transformation n t m)
Monad (Transformation n t m)
-> (forall a. IO a -> Transformation n t m a)
-> MonadIO (Transformation n t m)
IO a -> Transformation n t m a
forall a. IO a -> Transformation n t m a
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *).
MonadIO m =>
Monad (Transformation n t m)
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
MonadIO m =>
IO a -> Transformation n t m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: IO a -> Transformation n t m a
$cliftIO :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
MonadIO m =>
IO a -> Transformation n t m a
$cp1MonadIO :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *).
MonadIO m =>
Monad (Transformation n t m)
MonadIO)
    deriving (m a -> Transformation n t m a
(forall (m :: * -> *) a. Monad m => m a -> Transformation n t m a)
-> MonadTrans (Transformation n t)
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Monad m =>
m a -> Transformation n t m a
forall (m :: * -> *) a. Monad m => m a -> Transformation n t m a
forall (t :: Transformer).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: m a -> Transformation n t m a
$clift :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Monad m =>
m a -> Transformation n t m a
MonadTrans, MonadTrans (Transformation n t)
m (StT (Transformation n t) a) -> Transformation n t m a
MonadTrans (Transformation n t)
-> (forall (m :: * -> *) a.
    Monad m =>
    (Run (Transformation n t) -> m a) -> Transformation n t m a)
-> (forall (m :: * -> *) a.
    Monad m =>
    m (StT (Transformation n t) a) -> Transformation n t m a)
-> MonadTransControl (Transformation n t)
(Run (Transformation n t) -> m a) -> Transformation n t m a
forall k (n :: k -> *) (t :: k -> *).
MonadTrans (Transformation n t)
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Monad m =>
m (StT (Transformation n t) a) -> Transformation n t m a
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Monad m =>
(Run (Transformation n t) -> m a) -> Transformation n t m a
forall (m :: * -> *) a.
Monad m =>
m (StT (Transformation n t) a) -> Transformation n t m a
forall (m :: * -> *) a.
Monad m =>
(Run (Transformation n t) -> m a) -> Transformation n t m a
forall (t :: Transformer).
MonadTrans t
-> (forall (m :: * -> *) a. Monad m => (Run t -> m a) -> t m a)
-> (forall (m :: * -> *) a. Monad m => m (StT t a) -> t m a)
-> MonadTransControl t
restoreT :: m (StT (Transformation n t) a) -> Transformation n t m a
$crestoreT :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Monad m =>
m (StT (Transformation n t) a) -> Transformation n t m a
liftWith :: (Run (Transformation n t) -> m a) -> Transformation n t m a
$cliftWith :: forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Monad m =>
(Run (Transformation n t) -> m a) -> Transformation n t m a
$cp1MonadTransControl :: forall k (n :: k -> *) (t :: k -> *).
MonadTrans (Transformation n t)
MonadTransControl)
    deriving (MonadBase b, MonadBaseControl b)

instance Embed' tag t m => Embed' tag n (Transformation n t m) where
  embed' :: n a -> Transformation n t m a
embed' n a
na = ReaderT (F n t) m a -> Transformation n t m a
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
ReaderT (F n t) m a -> Transformation n t m a
Transformation (ReaderT (F n t) m a -> Transformation n t m a)
-> ((F n t -> m a) -> ReaderT (F n t) m a)
-> (F n t -> m a)
-> Transformation n t m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (F n t -> m a) -> ReaderT (F n t) m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((F n t -> m a) -> Transformation n t m a)
-> (F n t -> m a) -> Transformation n t m a
forall a b. (a -> b) -> a -> b
$
    \(F forall b. n b -> t b
f) -> t a -> m a
forall k (tag :: k) (n :: * -> *) (m :: * -> *) a.
Embed' tag n m =>
n a -> m a
embed' @tag (n a -> t a
forall b. n b -> t b
f n a
na)
  {-# INLINE embed' #-}

-- | Runs the embed effect by transforming the integrated monad @n@ into another
-- integrated monad @t@.
--
-- @since 0.3.0.0
runEmbed' :: forall tag n t m a
           . (forall b. n b -> t b)                      -- ^ The natural transformation from monad @n@ to monad @t@.
          -> (Embed' tag n `Via` Transformation n t) m a -- ^ The program whose embed effect should be handled.
          -> m a                                         -- ^ The program with its embed effect handled.
runEmbed' :: (forall b. n b -> t b)
-> Via (Embed' tag n) (Transformation n t) m a -> m a
runEmbed' forall b. n b -> t b
f = (ReaderT (F n t) m a -> F n t -> m a)
-> F n t -> ReaderT (F n t) m a -> m a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT (F n t) m a -> F n t -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ((forall b. n b -> t b) -> F n t
forall k (n :: k -> *) (t :: k -> *).
(forall (b :: k). n b -> t b) -> F n t
F forall b. n b -> t b
f) (ReaderT (F n t) m a -> m a)
-> (Via (Embed' tag n) (Transformation n t) m a
    -> ReaderT (F n t) m a)
-> Via (Embed' tag n) (Transformation n t) m a
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transformation n t m a -> ReaderT (F n t) m a
forall k (n :: k -> *) (t :: k -> *) (m :: * -> *) a.
Transformation n t m a -> ReaderT (F n t) m a
runTransformation (Transformation n t m a -> ReaderT (F n t) m a)
-> (Via (Embed' tag n) (Transformation n t) m a
    -> Transformation n t m a)
-> Via (Embed' tag n) (Transformation n t) m a
-> ReaderT (F n t) m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Via (Embed' tag n) (Transformation n t) m a
-> Transformation n t m a
forall (effs :: [Effect]) (t :: Transformer) (m :: * -> *) a.
EachVia effs t m a -> t m a
runVia
{-# INLINE runEmbed' #-}

-- | The untagged version of 'runEmbed''.
makeUntagged ['runEmbed']

-- | The finalization interpreter of the embed effect. This type implements the
-- 'Embed' type class by declaring the integrated monad the final monad @m@
-- (also called the \"base monad\").
--
-- Chances are very high that you only need this interpreter if you have a
-- custom final monad because the 'Embed'' effect is already implemented for
-- final monads like 'IO', 'Maybe', @[]@ and 'Identity'.
--
-- When interpreting the effect, you usually don\'t interact with this type directly,
-- but instead use one of its corresponding interpretation functions.
--
-- @since 0.3.0.0
newtype Finalization m a =
  Finalization { Finalization m a -> m a
_runFinalization :: m a }
    deriving (Functor (Finalization m)
a -> Finalization m a
Functor (Finalization m)
-> (forall a. a -> Finalization m a)
-> (forall a b.
    Finalization m (a -> b) -> Finalization m a -> Finalization m b)
-> (forall a b c.
    (a -> b -> c)
    -> Finalization m a -> Finalization m b -> Finalization m c)
-> (forall a b.
    Finalization m a -> Finalization m b -> Finalization m b)
-> (forall a b.
    Finalization m a -> Finalization m b -> Finalization m a)
-> Applicative (Finalization m)
Finalization m a -> Finalization m b -> Finalization m b
Finalization m a -> Finalization m b -> Finalization m a
Finalization m (a -> b) -> Finalization m a -> Finalization m b
(a -> b -> c)
-> Finalization m a -> Finalization m b -> Finalization m c
forall a. a -> Finalization m a
forall a b.
Finalization m a -> Finalization m b -> Finalization m a
forall a b.
Finalization m a -> Finalization m b -> Finalization m b
forall a b.
Finalization m (a -> b) -> Finalization m a -> Finalization m b
forall a b c.
(a -> b -> c)
-> Finalization m a -> Finalization m b -> Finalization m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (Finalization m)
forall (m :: * -> *) a. Applicative m => a -> Finalization m a
forall (m :: * -> *) a b.
Applicative m =>
Finalization m a -> Finalization m b -> Finalization m a
forall (m :: * -> *) a b.
Applicative m =>
Finalization m a -> Finalization m b -> Finalization m b
forall (m :: * -> *) a b.
Applicative m =>
Finalization m (a -> b) -> Finalization m a -> Finalization m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> Finalization m a -> Finalization m b -> Finalization m c
<* :: Finalization m a -> Finalization m b -> Finalization m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
Finalization m a -> Finalization m b -> Finalization m a
*> :: Finalization m a -> Finalization m b -> Finalization m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
Finalization m a -> Finalization m b -> Finalization m b
liftA2 :: (a -> b -> c)
-> Finalization m a -> Finalization m b -> Finalization m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> Finalization m a -> Finalization m b -> Finalization m c
<*> :: Finalization m (a -> b) -> Finalization m a -> Finalization m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
Finalization m (a -> b) -> Finalization m a -> Finalization m b
pure :: a -> Finalization m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> Finalization m a
$cp1Applicative :: forall (m :: * -> *). Applicative m => Functor (Finalization m)
Applicative, a -> Finalization m b -> Finalization m a
(a -> b) -> Finalization m a -> Finalization m b
(forall a b. (a -> b) -> Finalization m a -> Finalization m b)
-> (forall a b. a -> Finalization m b -> Finalization m a)
-> Functor (Finalization m)
forall a b. a -> Finalization m b -> Finalization m a
forall a b. (a -> b) -> Finalization m a -> Finalization m b
forall (m :: * -> *) a b.
Functor m =>
a -> Finalization m b -> Finalization m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> Finalization m a -> Finalization m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Finalization m b -> Finalization m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> Finalization m b -> Finalization m a
fmap :: (a -> b) -> Finalization m a -> Finalization m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> Finalization m a -> Finalization m b
Functor, Applicative (Finalization m)
a -> Finalization m a
Applicative (Finalization m)
-> (forall a b.
    Finalization m a -> (a -> Finalization m b) -> Finalization m b)
-> (forall a b.
    Finalization m a -> Finalization m b -> Finalization m b)
-> (forall a. a -> Finalization m a)
-> Monad (Finalization m)
Finalization m a -> (a -> Finalization m b) -> Finalization m b
Finalization m a -> Finalization m b -> Finalization m b
forall a. a -> Finalization m a
forall a b.
Finalization m a -> Finalization m b -> Finalization m b
forall a b.
Finalization m a -> (a -> Finalization m b) -> Finalization m b
forall (m :: * -> *). Monad m => Applicative (Finalization m)
forall (m :: * -> *) a. Monad m => a -> Finalization m a
forall (m :: * -> *) a b.
Monad m =>
Finalization m a -> Finalization m b -> Finalization m b
forall (m :: * -> *) a b.
Monad m =>
Finalization m a -> (a -> Finalization m b) -> Finalization m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> Finalization m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> Finalization m a
>> :: Finalization m a -> Finalization m b -> Finalization m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
Finalization m a -> Finalization m b -> Finalization m b
>>= :: Finalization m a -> (a -> Finalization m b) -> Finalization m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
Finalization m a -> (a -> Finalization m b) -> Finalization m b
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (Finalization m)
Monad, Monad (Finalization m)
Monad (Finalization m)
-> (forall a. IO a -> Finalization m a) -> MonadIO (Finalization m)
IO a -> Finalization m a
forall a. IO a -> Finalization m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (Finalization m)
forall (m :: * -> *) a. MonadIO m => IO a -> Finalization m a
liftIO :: IO a -> Finalization m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> Finalization m a
$cp1MonadIO :: forall (m :: * -> *). MonadIO m => Monad (Finalization m)
MonadIO)
    deriving (m a -> Finalization m a
(forall (m :: * -> *) a. Monad m => m a -> Finalization m a)
-> MonadTrans Finalization
forall (m :: * -> *) a. Monad m => m a -> Finalization m a
forall (t :: Transformer).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: m a -> Finalization m a
$clift :: forall (m :: * -> *) a. Monad m => m a -> Finalization m a
MonadTrans, MonadTrans Finalization
m (StT Finalization a) -> Finalization m a
MonadTrans Finalization
-> (forall (m :: * -> *) a.
    Monad m =>
    (Run Finalization -> m a) -> Finalization m a)
-> (forall (m :: * -> *) a.
    Monad m =>
    m (StT Finalization a) -> Finalization m a)
-> MonadTransControl Finalization
(Run Finalization -> m a) -> Finalization m a
forall (m :: * -> *) a.
Monad m =>
m (StT Finalization a) -> Finalization m a
forall (m :: * -> *) a.
Monad m =>
(Run Finalization -> m a) -> Finalization m a
forall (t :: Transformer).
MonadTrans t
-> (forall (m :: * -> *) a. Monad m => (Run t -> m a) -> t m a)
-> (forall (m :: * -> *) a. Monad m => m (StT t a) -> t m a)
-> MonadTransControl t
restoreT :: m (StT Finalization a) -> Finalization m a
$crestoreT :: forall (m :: * -> *) a.
Monad m =>
m (StT Finalization a) -> Finalization m a
liftWith :: (Run Finalization -> m a) -> Finalization m a
$cliftWith :: forall (m :: * -> *) a.
Monad m =>
(Run Finalization -> m a) -> Finalization m a
$cp1MonadTransControl :: MonadTrans Finalization
MonadTransControl) via IdentityT
    deriving (MonadBase b, MonadBaseControl b)

instance Monad n => Embed' tag n (Finalization n) where
  embed' :: n a -> Finalization n a
embed' = n a -> Finalization n a
forall k (m :: k -> *) (a :: k). m a -> Finalization m a
Finalization
  {-# INLINE embed' #-}

-- | Runs the embed effect by declaring the integrated monad the final monad.
--
-- @since 0.3.0.0
runFinal' :: (Embed' tag m `Via` Finalization) m a -- ^ The program whose embed effect should be handled.
          -> m a                                   -- ^ The program with its embed effect handled.
runFinal' :: Via (Embed' tag m) Finalization m a -> m a
runFinal' = Via (Embed' tag m) Finalization m a -> m a
coerce
{-# INLINE runFinal' #-}

-- | The untagged version of 'runFinal''.
--
-- @since 0.3.0.0
makeUntagged ['runFinal']