module Data.Apiary.Extension
( Has(getExtension)
, MonadExts(..), getExt
, Middleware'
, Extension(..)
, Extensions
, noExtension
, Initializer, initializer
, Initializer', initializer'
, initializerBracket
, initializerBracket'
, (+>)
) where
import Control.Monad(liftM)
import Data.Apiary.Extension.Internal(Has, getExtension, Initializer(Initializer))
import Control.Monad.Apiary.Action.Internal
(MonadExts(getExts), Extension(..), Extensions(AddExtension), Middleware')
getExt :: (MonadExts es m, Has e es) => proxy e -> m e
getExt p = getExtension p `liftM` getExts
type Initializer' m a = forall i. Initializer m i (a ': i)
addExtension :: Extension e => e -> Extensions es -> Extensions (e ': es)
addExtension = AddExtension
initializer :: (Extension e, Monad m) => (Extensions es -> m e) -> Initializer m es (e ': es)
initializer m = Initializer $ \es n -> do
e <- m es
n (addExtension e es)
initializer' :: (Extension e, Monad m) => m e -> Initializer' m e
initializer' m = initializer (const m)
initializerBracket :: Extension e => (forall a. Extensions es -> (e -> m a) -> m a) -> Initializer m es (e ': es)
initializerBracket b = Initializer $ \es n ->
b es $ \e -> n (addExtension e es)
initializerBracket' :: Extension e => (forall a. (e -> m a) -> m a) -> Initializer m es (e ': es)
initializerBracket' m = initializerBracket (const m)
(+>) :: Monad m => Initializer m i x -> Initializer m x o -> Initializer m i o
Initializer a +> Initializer b = Initializer $ \e m -> a e (\e' -> b e' m)
noExtension :: Monad m => Initializer m i i
noExtension = Initializer $ \es n -> n es