{-# LANGUAGE CPP, TupleSections #-}
{-# OPTIONS_HADDOCK not-home #-}
module Control.Effect.Type.Optional
(
Optional(..)
, threadRegionalViaOptional
) where
import Data.Functor.Const
import Control.Effect.Internal.Union
import Control.Effect.Type.Regional
import Control.Monad.Trans.Reader (ReaderT(..), mapReaderT)
import Control.Monad.Trans.Except (ExceptT(..), mapExceptT)
import qualified Control.Monad.Trans.State.Strict as SSt
import qualified Control.Monad.Trans.State.Lazy as LSt
import qualified Control.Monad.Trans.Writer.Lazy as LWr
import qualified Control.Monad.Trans.Writer.Strict as SWr
import qualified Control.Monad.Trans.Writer.CPS as CPSWr
data Optional s m a where
Optionally :: s a -> m a -> Optional s m a
threadRegionalViaOptional :: ( ThreadsEff t (Optional (Const s))
, Monad m)
=> (forall x. Regional s m x -> m x)
-> Regional s (t m) a -> t m a
threadRegionalViaOptional alg (Regionally s m) =
threadEff
(\(Optionally (Const s') m') -> alg (Regionally s' m'))
(Optionally (Const s) m)
{-# INLINE threadRegionalViaOptional #-}
instance Functor s => ThreadsEff (ExceptT e) (Optional s) where
threadEff alg (Optionally sa m) = mapExceptT (alg . Optionally (fmap Right sa)) m
{-# INLINE threadEff #-}
instance ThreadsEff (ReaderT i) (Optional s) where
threadEff alg (Optionally sa m) = mapReaderT (alg . Optionally sa) m
{-# INLINE threadEff #-}
instance Functor s => ThreadsEff (SSt.StateT s') (Optional s) where
threadEff alg (Optionally sa m) = SSt.StateT $ \s ->
alg $ Optionally (fmap (, s) sa) (SSt.runStateT m s)
{-# INLINE threadEff #-}
instance Functor s => ThreadsEff (LSt.StateT s') (Optional s) where
threadEff alg (Optionally sa m) = LSt.StateT $ \s ->
alg $ Optionally (fmap (, s) sa) (LSt.runStateT m s)
{-# INLINE threadEff #-}
instance (Functor s, Monoid w) => ThreadsEff (LWr.WriterT w) (Optional s) where
threadEff alg (Optionally sa m) =
LWr.mapWriterT (alg . Optionally (fmap (, mempty) sa)) m
{-# INLINE threadEff #-}
instance (Functor s, Monoid w) => ThreadsEff (SWr.WriterT w) (Optional s) where
threadEff alg (Optionally sa m) =
SWr.mapWriterT (alg . Optionally (fmap (, mempty) sa)) m
{-# INLINE threadEff #-}
instance (Functor s, Monoid w)
=> ThreadsEff (CPSWr.WriterT w) (Optional s) where
threadEff alg (Optionally sa m) =
CPSWr.mapWriterT (alg . Optionally (fmap (, mempty) sa)) m
{-# INLINE threadEff #-}