Safe Haskell | None |
---|---|
Language | Haskell2010 |
This module contains examples of simple advices.
BEWARE! These are provided for illustrative purposes only, they strive for simplicity and not robustness or efficiency.
Synopsis
- returnMempty :: forall ca e m r. (Monad m, Monoid r) => Advice ca e m r
- printArgs :: forall e m r. MonadIO m => Handle -> String -> Advice Show e m r
- doLocally :: forall ca e m r. Monad m => (forall n. e n -> e n) -> Advice ca e m r
- data AnyEq where
- doCachingBadly :: forall e m r. Monad m => (AnyEq -> m (Maybe r)) -> (AnyEq -> r -> m ()) -> Advice (Eq `And` Typeable) e m r
- doAsyncBadly :: forall ca e. Advice ca e IO ()
Basic advices
doLocally :: forall ca e m r. Monad m => (forall n. e n -> e n) -> Advice ca e m r Source #
Use local
on the final DepT
action of a function.
Allows tweaking the environment that will be seen by the function and all of its sub-calls.
>>>
:{
type HasLogger :: Type -> (Type -> Type) -> Constraint class HasLogger em m | em -> m where logger :: em -> String -> m () type Env :: (Type -> Type) -> Type data Env m = Env { _logger1 :: String -> m (), _logger2 :: String -> m (), _controllerA :: Int -> m (), _controllerB :: Int -> m () } instance HasLogger (Env m) m where logger = _logger1 envIO :: Env (DepT Env IO) envIO = Env { _logger1 = \_ -> liftIO $ putStrLn "logger1 ran", _logger2 = \_ -> liftIO $ putStrLn "logger2 ran", _controllerA = \_ -> do e <- ask; logger e "foo", _controllerB = advise @Top (doLocally \e@Env{_logger2} -> e {_logger1 = _logger2}) \_ -> do e <- ask; logger e "foo" } :}
>>>
runFromEnv (pure envIO) _controllerA 0
logger1 ran
>>>
runFromEnv (pure envIO) _controllerB 0
logger2 ran
A helper datatype for universal equality comparisons of existentialized values, used by doCachingBadly
.
For a more complete elaboration of this idea, see the the "exinst" package.
doCachingBadly :: forall e m r. Monad m => (AnyEq -> m (Maybe r)) -> (AnyEq -> r -> m ()) -> Advice (Eq `And` Typeable) e m r Source #
Given the means for looking up and storing values in the underlying monad
m
, makes functions (inefficiently) cache their results.
Notice the equality constraints on the Advice
. This means that the monad
m
and the result type r
are known and fixed before building the advice.
Once built, the Advice
won't be polymorphic over them.
The implementation of this function makes use of the existential type
parameter u
of makeAdvice
, because the phase that processes the function
arguments needs to communicate the calculated AnyEq
cache key to the phase
that processes the function result.
A better implementation of this advice would likely use an AnyHashable
helper datatype for the keys.