Copyright | Copyright 2024 Shea Levy. |
---|---|
License | Apache-2.0 |
Maintainer | shea@shealevy.com |
Safe Haskell | Safe-Inferred |
Language | GHC2021 |
This is the primary module needed to write a new EventBackend
and make it an EventBackendIn
relevant monads.
Synopsis
- class Event (BackendEvent backend) => EventBackend (backend :: Type) where
- type BackendEvent backend :: Type -> Type
- type RootSelector backend :: Type -> Type
- class (EventBackend backend, EventIn m (BackendEvent backend)) => EventBackendIn m backend where
- newEvent :: backend -> EventParams (RootSelector backend) field (EventReference (BackendEvent backend)) -> m (BackendEvent backend field)
- newInstantEvent :: backend -> EventParams (RootSelector backend) field (EventReference (BackendEvent backend)) -> m (EventReference (BackendEvent backend))
- data EventParams selector field reference = EventParams {}
- class Event (event :: Type -> Type) where
- type EventReference event :: Type
- reference :: event field -> EventReference event
- class (Event event, Monad m, ParametricFunctor m) => EventIn m event where
- finalize :: event field -> Maybe SomeException -> m ()
- addField :: event field -> field -> m ()
- data Selectors selector field where
- type family SubSelector field :: Type -> Type
Defining backends
class Event (BackendEvent backend) => EventBackend (backend :: Type) Source #
A resource allowing creation of new Event
s.
It must be an EventBackendIn
some monad to be useful.
type BackendEvent backend :: Type -> Type Source #
The Event
type this EventBackend
can generate.
Event
s are parameterized by the type of fields
they support.
type RootSelector backend :: Type -> Type Source #
The root of the selector tree this EventBackend
supports.
Instances
EventBackend (Proxy selector) Source # | An |
Defined in Observe.Event.Backend | |
EventBackend backend => EventBackend (SubEventBackend backend field) Source # | Create |
Defined in Observe.Event type BackendEvent (SubEventBackend backend field) :: Type -> Type Source # type RootSelector (SubEventBackend backend field) :: Type -> Type Source # | |
EventBackend (DataEventBackend m selector) Source # | Consume events by representing them as ordinary Haskell data. |
Defined in Observe.Event.Backend.Data type BackendEvent (DataEventBackend m selector) :: Type -> Type Source # type RootSelector (DataEventBackend m selector) :: Type -> Type Source # | |
(EventBackend b1, EventBackend b2, RootSelector b1 ~ RootSelector b2) => EventBackend (b1, b2) Source # | Combine two All operations are performed sequentially, with no exception safety between calls. |
Defined in Observe.Event.Backend type BackendEvent (b1, b2) :: Type -> Type Source # type RootSelector (b1, b2) :: Type -> Type Source # |
class (EventBackend backend, EventIn m (BackendEvent backend)) => EventBackendIn m backend where Source #
An EventBackend
which can be used in a given m
onad
:: backend | |
-> EventParams (RootSelector backend) field (EventReference (BackendEvent backend)) | Specify the event, matching the appropriate selector
type for this |
-> m (BackendEvent backend field) |
Create a new Event
with the given field
type.
Callers must ensure the resulting Event
is
finalize
d; the higher-level event initialization functions
take care of this for you.
newInstantEvent :: backend -> EventParams (RootSelector backend) field (EventReference (BackendEvent backend)) -> m (EventReference (BackendEvent backend)) Source #
Create an event which has no duration.
Returns a reference to the event.
Instances
data EventParams selector field reference Source #
Parameters specifying a new Event
EventParams | |
|
Defining event types
class Event (event :: Type -> Type) where Source #
A resource allowing instrumentation of code via fields of a given type.
It must be an EventIn
some monad to be useful.
type EventReference event :: Type Source #
The type of references to an Event
.
Instances
Event (Const () :: Type -> Type) Source # | An |
Defined in Observe.Event.Backend type EventReference (Const ()) Source # | |
(Event e1, Event e2) => Event (Product e1 e2) Source # | Combine two All operations are performed sequentially, with no exception safety between calls. |
Defined in Observe.Event.Backend type EventReference (Product e1 e2) Source # |
class (Event event, Monad m, ParametricFunctor m) => EventIn m event where Source #
finalize :: event field -> Maybe SomeException -> m () Source #
Instances
(Monad m, ParametricFunctor m) => EventIn m (Const () :: Type -> Type) Source # | An |
(EventIn m e1, EventIn m e2) => EventIn m (Product e1 e2) Source # | Combine two All operations are performed sequentially, with no exception safety between calls. |
(EventIn m event, ParametricMonadTrans t, MonadTransMonadConstraint t m) => EventIn (t m) event Source # | Lift an Note that this instance is incoherent,
so it can be overridden for your |
Defined in Observe.Event.Backend |
Selectors
data Selectors selector field where Source #
A nested sequence of selectors, starting from a
given root selector
family and ending in a selector
selecting a given field
type.
For example, given:
data FooSelector :: Type -> Type where Foo :: FooSelector FooField data FooField type instance SubSelector FooField = BarSelector data BarSelector :: Type -> Type where Bar :: BarSelector BarField data BarField type instance SubSelector BarField = NoEventsSelector
Then Leaf Foo
is a sequence Selectors
picking out an Event
with field
type FooField
, and Foo :/ Leaf Bar
is a sequence of Selectors
picking out
an Event
with field type BarField
underneath an Event
with field type FooField
.
See the selector and field documentation for more details.
type family SubSelector field :: Type -> Type Source #
The selector type for sub-Event
s underneath
an Event
of the given field
type.
Instrumented code will typically involve nested scopes of events, including calls across
different modules, with different types of events expected in different contexts. To support
this, each field type has an associated SubSelector
type to identify the kind of events
that can occur in the scope where the event is active. This results in a tree of event
types represented by a tree of selectors, reflecting the tree of instrumented source
components: Each selector of the root selector type specifies a field type, which in turn
specifies yet another selector (and, with it, its sub-tree). Use cases which require picking
out a linear path through this tree can use Selectors
.
If there are no sub-Event
s under Event
s with field type f
, then you can use
NoEventsSelector
: type instance SubSelector f = NoEventsSelector
.
If you want to retain the set of possible event types as in the parent scope, simply set
SubSelector
to the very same selector type that the parent selector came from.