Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This module provides an environment which tracks the dependencies of components that are added to it, allowing you to check if all dependencies are satisfied before running the program logic.
>>>
:{
newtype Foo d = Foo {foo :: String -> d ()} deriving Generic newtype Bar d = Bar {bar :: String -> d ()} deriving Generic makeIOFoo :: MonadIO m => Foo m makeIOFoo = Foo (liftIO . putStrLn) makeBar :: Has Foo m env => env -> Bar m makeBar (asCall -> call) = Bar (call foo) env :: CheckedEnv Identity IO env = mempty & checkedDep @Foo @'[] @'[MonadIO] (fromBare (\_ -> makeIOFoo)) & checkedDep @Bar @'[Foo] @'[] (fromBare makeBar) envReady :: DynamicEnv Identity IO envReady = let Right (_, pullPhase -> Identity checked) = checkEnv env in fixEnv checked :}
>>>
:{
bar (dep envReady) "this is bar" :} this is bar
An example of a failed check:
>>>
:{
badEnv :: CheckedEnv Identity IO badEnv = mempty & checkedDep @Bar @'[Foo] @'[] (fromBare makeBar) :}
>>>
:{
let Left missing = checkEnv badEnv in missing :} fromList [Foo]
Synopsis
- data CheckedEnv h m
- checkedDep :: forall r_ rs mcs h m. (All Typeable rs, All Typeable mcs, Typeable r_, Typeable h, Typeable m, HasAll rs m (DynamicEnv Identity m), Monad m, MonadSatisfiesAll mcs m) => (forall e n. (HasAll rs n e, Monad m, MonadSatisfiesAll mcs n) => (h `Compose` Constructor e) (r_ n)) -> CheckedEnv h m -> CheckedEnv h m
- getUnchecked :: CheckedEnv h m -> (DepGraph, DynamicEnv (h `Compose` Constructor (DynamicEnv Identity m)) m)
- checkEnv :: CheckedEnv h m -> Either (HashSet SomeDepRep) (DepGraph, DynamicEnv (h `Compose` Constructor (DynamicEnv Identity m)) m)
- data DepGraph = DepGraph {}
- data SomeMonadConstraintRep where
- SomeMonadConstraintRep :: forall (a :: (Type -> Type) -> Constraint). !(TypeRep a) -> SomeMonadConstraintRep
- monadConstraintRep :: forall (mc :: (Type -> Type) -> Constraint). Typeable mc => SomeMonadConstraintRep
- mempty :: Monoid a => a
A checked environment
data CheckedEnv h m Source #
A dependency injection environment for components with effects in the monad m
.
Parameterized by an Applicative
phase h
, and the type m
of the effect monad.
Instances
Monoid (CheckedEnv h m) Source # |
|
Defined in Dep.SimpleChecked mempty :: CheckedEnv h m # mappend :: CheckedEnv h m -> CheckedEnv h m -> CheckedEnv h m # mconcat :: [CheckedEnv h m] -> CheckedEnv h m # | |
Semigroup (CheckedEnv h m) Source # |
|
Defined in Dep.SimpleChecked (<>) :: CheckedEnv h m -> CheckedEnv h m -> CheckedEnv h m # sconcat :: NonEmpty (CheckedEnv h m) -> CheckedEnv h m # stimes :: Integral b => b -> CheckedEnv h m -> CheckedEnv h m # |
:: forall r_ rs mcs h m. (All Typeable rs, All Typeable mcs, Typeable r_, Typeable h, Typeable m, HasAll rs m (DynamicEnv Identity m), Monad m, MonadSatisfiesAll mcs m) | |
=> (forall e n. (HasAll rs n e, Monad m, MonadSatisfiesAll mcs n) => (h `Compose` Constructor e) (r_ n)) | The wrapped component |
-> CheckedEnv h m | The environment in which to insert |
-> CheckedEnv h m |
Add a component to a CheckedEnv
.
TYPE APPLICATIONS REQUIRED. You must provide three types using TypeApplications
:
- The type
r_
of the parameterizable record we want to add to the environment. - The type-level list
rs
of the components ther_
value depends on (might be empty). - The type-level list
mcs
of the constraints ther_
value requires from the base monad (might be empty).
It's impossible to add a component without explicitly listing all its dependencies.
In addition, you must also provide the (h
value, an implementation of the component that comes
wrapped in some Compose
Constructor e)Applicative
. Notice that this value must be sufficiently polymorphic.
getUnchecked :: CheckedEnv h m -> (DepGraph, DynamicEnv (h `Compose` Constructor (DynamicEnv Identity m)) m) Source #
Extract the underlying DynamicEnv
along with the dependency graph, without checking that all dependencies are satisfied.
checkEnv :: CheckedEnv h m -> Either (HashSet SomeDepRep) (DepGraph, DynamicEnv (h `Compose` Constructor (DynamicEnv Identity m)) m) Source #
Either fail with a the set of missing dependencies, or
succeed and produce the the underlying DynamicEnv
along with the
dependency graph.
The dependency graph
A summary graph of dependencies. If the required dependencies are not a subset of the provided ones, the environment is not yet complete.
The graph datatypes come from the algebraic-graphs package.
DepGraph | |
|
data SomeMonadConstraintRep where Source #
The type rep of a constraint over a monad. Similar to SomeTypeRep
but for types of a more specific kind.
SomeMonadConstraintRep :: forall (a :: (Type -> Type) -> Constraint). !(TypeRep a) -> SomeMonadConstraintRep |
Instances
monadConstraintRep :: forall (mc :: (Type -> Type) -> Constraint). Typeable mc => SomeMonadConstraintRep Source #
Produce a SomeMonadConstraintRep
by means of a type application.