module Control.Monad.Classes.Exec
( MonadExec
, exec
, MonadExecN(..)
, EffExec
)
where
import Control.Monad.Trans.Class
import GHC.Prim (Proxy#, proxy#)
import Control.Monad.Classes.Core
import Control.Monad.Classes.Effects
import Data.Peano (Peano (..))
type instance CanDo IO (EffExec IO) = True
class Monad m => MonadExecN (n :: Peano) w m where
execN :: Proxy# n -> (w a -> m a)
instance Monad w => MonadExecN Zero w w where
execN _ = id
instance (MonadTrans t, Monad (t m), MonadExecN n w m, Monad m)
=> MonadExecN (Succ n) w (t m)
where
execN _ = lift . execN (proxy# :: Proxy# n)
type MonadExec w m = MonadExecN (Find (EffExec w) m) w m
exec :: forall w m a . MonadExec w m => w a -> m a
exec = execN (proxy# :: Proxy# (Find (EffExec w) m))