{-# LANGUAGE TemplateHaskell #-}

-- | Something for converting polysemy actions into monadic actions
module CalamityCommands.Internal.RunIntoM
    ( runSemToM
    , bindSemToM ) where

import           Data.Functor

import qualified Polysemy                         as P
import qualified Polysemy.Final                   as P

runSemToM :: forall m r a. (Monad m, P.Member (P.Final m) r) => P.Sem r a -> P.Sem r (m (Maybe a))
runSemToM :: Sem r a -> Sem r (m (Maybe a))
runSemToM Sem r a
m = Strategic m (Sem r) (m (Maybe a)) -> Sem r (m (Maybe a))
forall (m :: * -> *) (r :: EffectRow) a.
Member (Final m) r =>
Strategic m (Sem r) a -> Sem r a
P.withStrategicToFinal (Strategic m (Sem r) (m (Maybe a)) -> Sem r (m (Maybe a)))
-> Strategic m (Sem r) (m (Maybe a)) -> Sem r (m (Maybe a))
forall a b. (a -> b) -> a -> b
$ do
  m (f a)
m' <- Sem r a -> Sem (WithStrategy m f (Sem r)) (m (f a))
forall (n :: * -> *) a (m :: * -> *) (f :: * -> *).
n a -> Sem (WithStrategy m f n) (m (f a))
P.runS Sem r a
m
  Inspector f
ins <- Sem (WithStrategy m f (Sem r)) (Inspector f)
forall (m :: * -> *) (f :: * -> *) (n :: * -> *).
Sem (WithStrategy m f n) (Inspector f)
P.getInspectorS
  m (m (Maybe a)) -> Strategic m (Sem r) (m (Maybe a))
forall (m :: * -> *) a (n :: * -> *).
Functor m =>
m a -> Strategic m n a
P.liftS (m (m (Maybe a)) -> Strategic m (Sem r) (m (Maybe a)))
-> m (m (Maybe a)) -> Strategic m (Sem r) (m (Maybe a))
forall a b. (a -> b) -> a -> b
$ m (Maybe a) -> m (m (Maybe a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Inspector f -> forall x. f x -> Maybe x
forall (f :: * -> *). Inspector f -> forall x. f x -> Maybe x
P.inspect Inspector f
ins (f a -> Maybe a) -> m (f a) -> m (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (f a)
m')

bindSemToM :: forall m r p a. (Monad m, P.Member (P.Final m) r) => (p -> P.Sem r a) -> P.Sem r (p -> m (Maybe a))
bindSemToM :: (p -> Sem r a) -> Sem r (p -> m (Maybe a))
bindSemToM p -> Sem r a
m = Strategic m (Sem r) (p -> m (Maybe a)) -> Sem r (p -> m (Maybe a))
forall (m :: * -> *) (r :: EffectRow) a.
Member (Final m) r =>
Strategic m (Sem r) a -> Sem r a
P.withStrategicToFinal (Strategic m (Sem r) (p -> m (Maybe a))
 -> Sem r (p -> m (Maybe a)))
-> Strategic m (Sem r) (p -> m (Maybe a))
-> Sem r (p -> m (Maybe a))
forall a b. (a -> b) -> a -> b
$ do
  f ()
istate <- Sem (WithStrategy m f (Sem r)) (f ())
forall (m :: * -> *) (f :: * -> *) (n :: * -> *).
Sem (WithStrategy m f n) (f ())
P.getInitialStateS
  f p -> m (f a)
m' <- (p -> Sem r a) -> Sem (WithStrategy m f (Sem r)) (f p -> m (f a))
forall a (n :: * -> *) b (m :: * -> *) (f :: * -> *).
(a -> n b) -> Sem (WithStrategy m f n) (f a -> m (f b))
P.bindS p -> Sem r a
m
  Inspector f
ins <- Sem (WithStrategy m f (Sem r)) (Inspector f)
forall (m :: * -> *) (f :: * -> *) (n :: * -> *).
Sem (WithStrategy m f n) (Inspector f)
P.getInspectorS
  m (p -> m (Maybe a)) -> Strategic m (Sem r) (p -> m (Maybe a))
forall (m :: * -> *) a (n :: * -> *).
Functor m =>
m a -> Strategic m n a
P.liftS (m (p -> m (Maybe a)) -> Strategic m (Sem r) (p -> m (Maybe a)))
-> m (p -> m (Maybe a)) -> Strategic m (Sem r) (p -> m (Maybe a))
forall a b. (a -> b) -> a -> b
$ (p -> m (Maybe a)) -> m (p -> m (Maybe a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (\p
x -> Inspector f -> forall x. f x -> Maybe x
forall (f :: * -> *). Inspector f -> forall x. f x -> Maybe x
P.inspect Inspector f
ins (f a -> Maybe a) -> m (f a) -> m (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f p -> m (f a)
m' (f ()
istate f () -> p -> f p
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> p
x))