{-# LANGUAGE TemplateHaskell #-}

module Polysemy.Embed
  ( -- * Effect
    Embed (..)

    -- * Actions
  , embed

    -- * Interpretations
  , runEmbedded
  ) where

import Polysemy

------------------------------------------------------------------------------
-- | Given a natural transform from @m1@ to @m2@
-- run a @Embed m1@ effect by transforming it into a @Embed m2@ effect.
--
-- @since 1.0.0.0
runEmbedded
    :: forall m1 m2 r a
     . Member (Embed m2) r
    => (forall x. m1 x -> m2 x)
    -> Sem (Embed m1 ': r) a
    -> Sem r a
runEmbedded :: (forall x. m1 x -> m2 x) -> Sem (Embed m1 : r) a -> Sem r a
runEmbedded forall x. m1 x -> m2 x
f = (forall (rInitial :: EffectRow) x.
 Embed m1 (Sem rInitial) x -> Sem r x)
-> Sem (Embed m1 : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret ((forall (rInitial :: EffectRow) x.
  Embed m1 (Sem rInitial) x -> Sem r x)
 -> Sem (Embed m1 : r) a -> Sem r a)
-> (forall (rInitial :: EffectRow) x.
    Embed m1 (Sem rInitial) x -> Sem r x)
-> Sem (Embed m1 : r) a
-> Sem r a
forall a b. (a -> b) -> a -> b
$ m2 x -> Sem r x
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (m2 x -> Sem r x)
-> (Embed m1 (Sem rInitial) x -> m2 x)
-> Embed m1 (Sem rInitial) x
-> Sem r x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m1 x -> m2 x
forall x. m1 x -> m2 x
f (m1 x -> m2 x)
-> (Embed m1 (Sem rInitial) x -> m1 x)
-> Embed m1 (Sem rInitial) x
-> m2 x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Embed m1 (Sem rInitial) x -> m1 x
forall (m :: * -> *) (z :: * -> *) a. Embed m z a -> m a
unEmbed
{-# INLINE runEmbedded #-}