module Pandora.Paradigm.Controlflow.Observable (Observable, observe,
	notify, follow, subscribe, watch, (.:~.), (.:~*), (*:~.), (*:~*)) where

import Pandora.Pattern.Category ((.), ($))
import Pandora.Pattern.Functor.Applicative (Applicative (forever))
import Pandora.Paradigm.Primary.Transformer.Continuation (Continuation (Continuation, continue))

newtype Capture r t a = Capture { Capture r t a -> t r
captured :: t r }

type Observable t a r = Continuation r (Capture r t) a

-- | Make continuation observable
observe :: Continuation r t a -> Observable t a r
observe :: Continuation r t a -> Observable t a r
observe Continuation r t a
action = ((((->) ::|:. a) :. Capture r t) := r) -> Observable t a r
forall k (r :: k) (t :: k -> *) a.
((((->) ::|:. a) :. t) := r) -> Continuation r t a
Continuation (((((->) ::|:. a) :. Capture r t) := r) -> Observable t a r)
-> ((((->) ::|:. a) :. Capture r t) := r) -> Observable t a r
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ \a -> Capture r t r
h -> t r -> Capture r t r
forall k k (r :: k) (t :: k -> *) (a :: k). t r -> Capture r t a
Capture (t r -> Capture r t r) -> t r -> Capture r t r
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ Continuation r t a -> (((->) ::|:. a) :. t) := r
forall k (r :: k) (t :: k -> *) a.
Continuation r t a -> (((->) ::|:. a) :. t) := r
continue Continuation r t a
action (Capture r t r -> t r
forall k (r :: k) (t :: k -> *) k (a :: k). Capture r t a -> t r
captured (Capture r t r -> t r) -> (a -> Capture r t r) -> a -> t r
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. a -> Capture r t r
h)

-- | Listen only first event, call back just once
notify :: Observable t a r -> (a -> t r) -> t r
notify :: Observable t a r -> (a -> t r) -> t r
notify Observable t a r
r a -> t r
action = Capture r t r -> t r
forall k (r :: k) (t :: k -> *) k (a :: k). Capture r t a -> t r
captured (Capture r t r -> t r) -> Capture r t r -> t r
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ Observable t a r -> (((->) ::|:. a) :. Capture r t) := r
forall k (r :: k) (t :: k -> *) a.
Continuation r t a -> (((->) ::|:. a) :. t) := r
continue Observable t a r
r (t r -> Capture r t r
forall k k (r :: k) (t :: k -> *) (a :: k). t r -> Capture r t a
Capture (t r -> Capture r t r) -> (a -> t r) -> a -> Capture r t r
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. a -> t r
action)

-- | Infix version of 'notify'
(.:~.) :: Observable t a r -> (a -> t r) -> t r
.:~. :: Observable t a r -> (a -> t r) -> t r
(.:~.) = Observable t a r -> (a -> t r) -> t r
forall k (t :: k -> *) a (r :: k).
Observable t a r -> (a -> t r) -> t r
notify

-- | Listen only first event, call back forever
follow :: Applicative t => Observable t a r -> (a -> t r) -> t r
follow :: Observable t a r -> (a -> t r) -> t r
follow Observable t a r
r a -> t r
action = Capture r t r -> t r
forall k (r :: k) (t :: k -> *) k (a :: k). Capture r t a -> t r
captured (Capture r t r -> t r) -> Capture r t r -> t r
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ Observable t a r -> (((->) ::|:. a) :. Capture r t) := r
forall k (r :: k) (t :: k -> *) a.
Continuation r t a -> (((->) ::|:. a) :. t) := r
continue Observable t a r
r (t r -> Capture r t r
forall k k (r :: k) (t :: k -> *) (a :: k). t r -> Capture r t a
Capture (t r -> Capture r t r) -> (a -> t r) -> a -> Capture r t r
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. t r -> t r
forall (t :: * -> *) a b. Applicative t => t a -> t b
forever (t r -> t r) -> (a -> t r) -> a -> t r
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. a -> t r
action)

-- | Infix version of 'follow'
(.:~*) :: Applicative t => Observable t a r -> (a -> t r) -> t r
.:~* :: Observable t a r -> (a -> t r) -> t r
(.:~*) = Observable t a r -> (a -> t r) -> t r
forall (t :: * -> *) a r.
Applicative t =>
Observable t a r -> (a -> t r) -> t r
follow

-- | Listen all events from action, call back just once
subscribe :: Applicative t => Observable t a r -> (a -> t r) -> t r
subscribe :: Observable t a r -> (a -> t r) -> t r
subscribe Observable t a r
r a -> t r
action = t r -> t r
forall (t :: * -> *) a b. Applicative t => t a -> t b
forever (t r -> t r) -> t r -> t r
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ Capture r t r -> t r
forall k (r :: k) (t :: k -> *) k (a :: k). Capture r t a -> t r
captured (Capture r t r -> t r) -> Capture r t r -> t r
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ Observable t a r -> (((->) ::|:. a) :. Capture r t) := r
forall k (r :: k) (t :: k -> *) a.
Continuation r t a -> (((->) ::|:. a) :. t) := r
continue Observable t a r
r (t r -> Capture r t r
forall k k (r :: k) (t :: k -> *) (a :: k). t r -> Capture r t a
Capture (t r -> Capture r t r) -> (a -> t r) -> a -> Capture r t r
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. a -> t r
action)

-- | Infix version of 'subscribe'
(*:~.) :: Applicative t => Observable t a r -> (a -> t r) -> t r
*:~. :: Observable t a r -> (a -> t r) -> t r
(*:~.) = Observable t a r -> (a -> t r) -> t r
forall (t :: * -> *) a r.
Applicative t =>
Observable t a r -> (a -> t r) -> t r
subscribe

-- | Listen all events from action, call back forever
watch :: Applicative t => Observable t a r -> (a -> t r) -> t r
watch :: Observable t a r -> (a -> t r) -> t r
watch Observable t a r
r a -> t r
action = t r -> t r
forall (t :: * -> *) a b. Applicative t => t a -> t b
forever (t r -> t r) -> t r -> t r
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ Capture r t r -> t r
forall k (r :: k) (t :: k -> *) k (a :: k). Capture r t a -> t r
captured (Capture r t r -> t r) -> Capture r t r -> t r
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ Observable t a r -> (((->) ::|:. a) :. Capture r t) := r
forall k (r :: k) (t :: k -> *) a.
Continuation r t a -> (((->) ::|:. a) :. t) := r
continue Observable t a r
r (t r -> Capture r t r
forall k k (r :: k) (t :: k -> *) (a :: k). t r -> Capture r t a
Capture (t r -> Capture r t r) -> (a -> t r) -> a -> Capture r t r
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. t r -> t r
forall (t :: * -> *) a b. Applicative t => t a -> t b
forever (t r -> t r) -> (a -> t r) -> a -> t r
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. a -> t r
action)

-- | Infix version of 'watch'
(*:~*) :: Applicative t => Observable t a r -> (a -> t r) -> t r
*:~* :: Observable t a r -> (a -> t r) -> t r
(*:~*) = Observable t a r -> (a -> t r) -> t r
forall (t :: * -> *) a r.
Applicative t =>
Observable t a r -> (a -> t r) -> t r
watch