{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UnicodeSyntax #-}
{-# OPTIONS_HADDOCK not-home #-}
module Observe.Event.Backend
(
EventBackend (..)
, EventBackendIn (..)
, EventParams (..)
, Event (..)
, EventIn (..)
, Selectors (..)
, SubSelector
)
where
import Control.Exception
import Control.Monad.Trans.Class
import Control.Monad.Trans.Class.Parametric
import Control.Monad.Zip
import Data.Functor.Const
import Data.Functor.Parametric
import Data.Functor.Product
import Data.Kind
import Data.Proxy
import Observe.Event.Compat
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
{ forall (selector :: * -> *) field reference.
EventParams selector field reference -> Selectors selector field
selectors ∷ !(Selectors selector field)
, forall (selector :: * -> *) field reference.
EventParams selector field reference -> Maybe reference
parent ∷ !(Maybe reference)
, forall (selector :: * -> *) field reference.
EventParams selector field reference -> [reference]
causes ∷ ![reference]
, forall (selector :: * -> *) field reference.
EventParams selector field reference -> [field]
initialFields ∷ ![field]
}
instance EventBackend (Proxy (selector ∷ Type → Type)) where
type BackendEvent (Proxy selector) = Const ()
type RootSelector (Proxy selector) = selector
instance (Monad m, ParametricFunctor m) ⇒ EventBackendIn m (Proxy (selector ∷ Type → Type)) where
newEvent :: forall field.
Proxy selector
-> EventParams
(RootSelector (Proxy selector))
field
(EventReference (BackendEvent (Proxy selector)))
-> m (BackendEvent (Proxy selector) field)
newEvent Proxy selector
_ EventParams
(RootSelector (Proxy selector))
field
(EventReference (BackendEvent (Proxy selector)))
_ = BackendEvent (Proxy selector) field
-> m (BackendEvent (Proxy selector) field)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (BackendEvent (Proxy selector) field
-> m (BackendEvent (Proxy selector) field))
-> BackendEvent (Proxy selector) field
-> m (BackendEvent (Proxy selector) field)
forall a b. (a -> b) -> a -> b
$ () -> Const () field
forall {k} a (b :: k). a -> Const a b
Const ()
newInstantEvent :: forall field.
Proxy selector
-> EventParams
(RootSelector (Proxy selector))
field
(EventReference (BackendEvent (Proxy selector)))
-> m (EventReference (BackendEvent (Proxy selector)))
newInstantEvent Proxy selector
_ EventParams
(RootSelector (Proxy selector))
field
(EventReference (BackendEvent (Proxy selector)))
_ = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
instance (EventBackend b1, EventBackend b2, RootSelector b1 ~ RootSelector b2) ⇒ EventBackend (b1, b2) where
type BackendEvent (b1, b2) = Product (BackendEvent b1) (BackendEvent b2)
type RootSelector (b1, b2) = RootSelector b1
instance (EventBackendIn m b1, EventBackendIn m b2, RootSelector b1 ~ RootSelector b2) ⇒ EventBackendIn m (b1, b2) where
newEvent :: forall field.
(b1, b2)
-> EventParams
(RootSelector (b1, b2))
field
(EventReference (BackendEvent (b1, b2)))
-> m (BackendEvent (b1, b2) field)
newEvent (b1
b1, b2
b2) EventParams
(RootSelector (b1, b2))
field
(EventReference (BackendEvent (b1, b2)))
args = BackendEvent b1 field
-> BackendEvent b2 field
-> Product (BackendEvent b1) (BackendEvent b2) field
forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair (BackendEvent b1 field
-> BackendEvent b2 field
-> Product (BackendEvent b1) (BackendEvent b2) field)
-> m (BackendEvent b1 field)
-> m (BackendEvent b2 field
-> Product (BackendEvent b1) (BackendEvent b2) field)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b1
-> EventParams
(RootSelector b1) field (EventReference (BackendEvent b1))
-> m (BackendEvent b1 field)
forall field.
b1
-> EventParams
(RootSelector b1) field (EventReference (BackendEvent b1))
-> m (BackendEvent b1 field)
forall (m :: * -> *) backend field.
EventBackendIn m backend =>
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (BackendEvent backend field)
newEvent b1
b1 EventParams
(RootSelector b1) field (EventReference (BackendEvent b1))
EventParams
(RootSelector b2) field (EventReference (BackendEvent b1))
args1 m (BackendEvent b2 field
-> Product (BackendEvent b1) (BackendEvent b2) field)
-> m (BackendEvent b2 field)
-> m (Product (BackendEvent b1) (BackendEvent b2) field)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> b2
-> EventParams
(RootSelector b2) field (EventReference (BackendEvent b2))
-> m (BackendEvent b2 field)
forall field.
b2
-> EventParams
(RootSelector b2) field (EventReference (BackendEvent b2))
-> m (BackendEvent b2 field)
forall (m :: * -> *) backend field.
EventBackendIn m backend =>
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (BackendEvent backend field)
newEvent b2
b2 EventParams
(RootSelector b2) field (EventReference (BackendEvent b2))
args2
where
(EventParams
(RootSelector b2) field (EventReference (BackendEvent b1))
args1, EventParams
(RootSelector b2) field (EventReference (BackendEvent b2))
args2) = EventParams
(RootSelector b2)
field
(EventReference (BackendEvent b1),
EventReference (BackendEvent b2))
-> (EventParams
(RootSelector b2) field (EventReference (BackendEvent b1)),
EventParams
(RootSelector b2) field (EventReference (BackendEvent b2)))
forall (selector :: * -> *) field r1 r2.
EventParams selector field (r1, r2)
-> (EventParams selector field r1, EventParams selector field r2)
unwrapPairParams EventParams
(RootSelector b2)
field
(EventReference (BackendEvent b1),
EventReference (BackendEvent b2))
EventParams
(RootSelector (b1, b2))
field
(EventReference (BackendEvent (b1, b2)))
args
newInstantEvent :: forall field.
(b1, b2)
-> EventParams
(RootSelector (b1, b2))
field
(EventReference (BackendEvent (b1, b2)))
-> m (EventReference (BackendEvent (b1, b2)))
newInstantEvent (b1
b1, b2
b2) EventParams
(RootSelector (b1, b2))
field
(EventReference (BackendEvent (b1, b2)))
args = (,) (EventReference (BackendEvent b1)
-> EventReference (BackendEvent b2)
-> (EventReference (BackendEvent b1),
EventReference (BackendEvent b2)))
-> m (EventReference (BackendEvent b1))
-> m (EventReference (BackendEvent b2)
-> (EventReference (BackendEvent b1),
EventReference (BackendEvent b2)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b1
-> EventParams
(RootSelector b1) field (EventReference (BackendEvent b1))
-> m (EventReference (BackendEvent b1))
forall field.
b1
-> EventParams
(RootSelector b1) field (EventReference (BackendEvent b1))
-> m (EventReference (BackendEvent b1))
forall (m :: * -> *) backend field.
EventBackendIn m backend =>
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (EventReference (BackendEvent backend))
newInstantEvent b1
b1 EventParams
(RootSelector b1) field (EventReference (BackendEvent b1))
EventParams
(RootSelector b2) field (EventReference (BackendEvent b1))
args1 m (EventReference (BackendEvent b2)
-> (EventReference (BackendEvent b1),
EventReference (BackendEvent b2)))
-> m (EventReference (BackendEvent b2))
-> m (EventReference (BackendEvent b1),
EventReference (BackendEvent b2))
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> b2
-> EventParams
(RootSelector b2) field (EventReference (BackendEvent b2))
-> m (EventReference (BackendEvent b2))
forall field.
b2
-> EventParams
(RootSelector b2) field (EventReference (BackendEvent b2))
-> m (EventReference (BackendEvent b2))
forall (m :: * -> *) backend field.
EventBackendIn m backend =>
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (EventReference (BackendEvent backend))
newInstantEvent b2
b2 EventParams
(RootSelector b2) field (EventReference (BackendEvent b2))
args2
where
(EventParams
(RootSelector b2) field (EventReference (BackendEvent b1))
args1, EventParams
(RootSelector b2) field (EventReference (BackendEvent b2))
args2) = EventParams
(RootSelector b2)
field
(EventReference (BackendEvent b1),
EventReference (BackendEvent b2))
-> (EventParams
(RootSelector b2) field (EventReference (BackendEvent b1)),
EventParams
(RootSelector b2) field (EventReference (BackendEvent b2)))
forall (selector :: * -> *) field r1 r2.
EventParams selector field (r1, r2)
-> (EventParams selector field r1, EventParams selector field r2)
unwrapPairParams EventParams
(RootSelector b2)
field
(EventReference (BackendEvent b1),
EventReference (BackendEvent b2))
EventParams
(RootSelector (b1, b2))
field
(EventReference (BackendEvent (b1, b2)))
args
instance {-# INCOHERENT #-} (EventBackendIn m backend, ParametricMonadTrans t, MonadTransMonadConstraint t m) ⇒ EventBackendIn (t m) backend where
newEvent :: forall field.
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> t m (BackendEvent backend field)
newEvent = (m (BackendEvent backend field) -> t m (BackendEvent backend field)
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift .) ((EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (BackendEvent backend field))
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> t m (BackendEvent backend field))
-> (backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (BackendEvent backend field))
-> backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> t m (BackendEvent backend field)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (BackendEvent backend field)
forall field.
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (BackendEvent backend field)
forall (m :: * -> *) backend field.
EventBackendIn m backend =>
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (BackendEvent backend field)
newEvent
newInstantEvent :: forall field.
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> t m (EventReference (BackendEvent backend))
newInstantEvent = (m (EventReference (BackendEvent backend))
-> t m (EventReference (BackendEvent backend))
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift .) ((EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (EventReference (BackendEvent backend)))
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> t m (EventReference (BackendEvent backend)))
-> (backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (EventReference (BackendEvent backend)))
-> backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> t m (EventReference (BackendEvent backend))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (EventReference (BackendEvent backend))
forall field.
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (EventReference (BackendEvent backend))
forall (m :: * -> *) backend field.
EventBackendIn m backend =>
backend
-> EventParams
(RootSelector backend)
field
(EventReference (BackendEvent backend))
-> m (EventReference (BackendEvent backend))
newInstantEvent
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 ()
instance Event (Const ()) where
type EventReference (Const ()) = ()
reference :: forall field. Const () field -> EventReference (Const ())
reference Const () field
_ = ()
instance (Monad m, ParametricFunctor m) ⇒ EventIn m (Const ()) where
finalize :: forall field. Const () field -> Maybe SomeException -> m ()
finalize Const () field
_ Maybe SomeException
_ = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
addField :: forall field. Const () field -> field -> m ()
addField Const () field
_ field
_ = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
instance (Event e1, Event e2) ⇒ Event (Product e1 e2) where
type EventReference (Product e1 e2) = (EventReference e1, EventReference e2)
reference :: forall field. Product e1 e2 field -> EventReference (Product e1 e2)
reference (Pair e1 field
e1 e2 field
e2) = (e1 field -> EventReference e1
forall field. e1 field -> EventReference e1
forall (event :: * -> *) field.
Event event =>
event field -> EventReference event
reference e1 field
e1, e2 field -> EventReference e2
forall field. e2 field -> EventReference e2
forall (event :: * -> *) field.
Event event =>
event field -> EventReference event
reference e2 field
e2)
instance (EventIn m e1, EventIn m e2) ⇒ EventIn m (Product e1 e2) where
finalize :: forall field. Product e1 e2 field -> Maybe SomeException -> m ()
finalize (Pair e1 field
e1 e2 field
e2) Maybe SomeException
err = e1 field -> Maybe SomeException -> m ()
forall field. e1 field -> Maybe SomeException -> m ()
forall (m :: * -> *) (event :: * -> *) field.
EventIn m event =>
event field -> Maybe SomeException -> m ()
finalize e1 field
e1 Maybe SomeException
err m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> e2 field -> Maybe SomeException -> m ()
forall field. e2 field -> Maybe SomeException -> m ()
forall (m :: * -> *) (event :: * -> *) field.
EventIn m event =>
event field -> Maybe SomeException -> m ()
finalize e2 field
e2 Maybe SomeException
err
addField :: forall field. Product e1 e2 field -> field -> m ()
addField (Pair e1 field
e1 e2 field
e2) field
f = e1 field -> field -> m ()
forall field. e1 field -> field -> m ()
forall (m :: * -> *) (event :: * -> *) field.
EventIn m event =>
event field -> field -> m ()
addField e1 field
e1 field
f m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> e2 field -> field -> m ()
forall field. e2 field -> field -> m ()
forall (m :: * -> *) (event :: * -> *) field.
EventIn m event =>
event field -> field -> m ()
addField e2 field
e2 field
f
unwrapPairParams ∷ EventParams selector field (r1, r2) → (EventParams selector field r1, EventParams selector field r2)
unwrapPairParams :: forall (selector :: * -> *) field r1 r2.
EventParams selector field (r1, r2)
-> (EventParams selector field r1, EventParams selector field r2)
unwrapPairParams EventParams selector field (r1, r2)
params =
( EventParams selector field (r1, r2)
params{parent = parent1, causes = causes1}
, EventParams selector field (r1, r2)
params{parent = parent2, causes = causes2}
)
where
(Maybe r1
parent1, Maybe r2
parent2) = Maybe (r1, r2) -> (Maybe r1, Maybe r2)
forall a b. Maybe (a, b) -> (Maybe a, Maybe b)
forall (m :: * -> *) a b. MonadZip m => m (a, b) -> (m a, m b)
munzip EventParams selector field (r1, r2)
params.parent
([r1]
causes1, [r2]
causes2) = [(r1, r2)] -> ([r1], [r2])
forall a b. [(a, b)] -> ([a], [b])
forall (m :: * -> *) a b. MonadZip m => m (a, b) -> (m a, m b)
munzip EventParams selector field (r1, r2)
params.causes
instance {-# INCOHERENT #-} (EventIn m event, ParametricMonadTrans t, MonadTransMonadConstraint t m) ⇒ EventIn (t m) event where
finalize :: forall field. event field -> Maybe SomeException -> t m ()
finalize = (m () -> t m ()
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift .) ((Maybe SomeException -> m ()) -> Maybe SomeException -> t m ())
-> (event field -> Maybe SomeException -> m ())
-> event field
-> Maybe SomeException
-> t m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. event field -> Maybe SomeException -> m ()
forall field. event field -> Maybe SomeException -> m ()
forall (m :: * -> *) (event :: * -> *) field.
EventIn m event =>
event field -> Maybe SomeException -> m ()
finalize
addField :: forall field. event field -> field -> t m ()
addField = (m () -> t m ()
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift .) ((field -> m ()) -> field -> t m ())
-> (event field -> field -> m ()) -> event field -> field -> t m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. event field -> field -> m ()
forall field. event field -> field -> m ()
forall (m :: * -> *) (event :: * -> *) field.
EventIn m event =>
event field -> field -> m ()
addField
data Selectors selector field where
Leaf ∷ selector field → Selectors selector field
(:/) ∷ selector field → Selectors (SubSelector field) field' → Selectors selector field'
infixr 5 :/
type family SubSelector field ∷ Type → Type