{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
module Control.Carrier.Empty.Maybe
(
runEmpty
, EmptyC(..)
, module Control.Effect.Empty
) where
import Control.Algebra
import Control.Effect.Empty
import qualified Control.Monad.Fail as Fail
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Control.Monad.Trans.Maybe
runEmpty :: EmptyC m a -> m (Maybe a)
runEmpty (EmptyC m) = runMaybeT m
{-# INLINE runEmpty #-}
newtype EmptyC m a = EmptyC (MaybeT m a)
deriving (Applicative, Functor, Monad, MonadFix, MonadIO, MonadTrans)
instance Fail.MonadFail m => Fail.MonadFail (EmptyC m) where
fail = lift . Fail.fail
{-# INLINE fail #-}
instance (Algebra sig m, Effect sig) => Algebra (Empty :+: sig) (EmptyC m) where
alg (L Empty) = EmptyC (MaybeT (pure Nothing))
alg (R other) = EmptyC (MaybeT (alg (thread (Just ()) (maybe (pure Nothing) runEmpty) other)))
{-# INLINE alg #-}