module Pandora.Paradigm.Controlflow.Observable (Observable, observe,
notify, follow, subscribe, watch, (.:~.), (.:~*), (*:~.), (*:~*)) where
import Pandora.Pattern.Category ((.))
import Pandora.Paradigm.Basis.Continuation (Continuation (Continuation, continue))
import Pandora.Pattern.Functor.Applicative (Applicative (forever))
import Pandora.Pattern.Functor.Divariant (($))
newtype Capture r t a = Capture { captured :: t r }
type Observable t a r = Continuation r (Capture r t) a
observe :: Continuation r t a -> Observable t a r
observe action = Continuation $ \h -> Capture $ continue action (captured . h)
notify :: Observable t a r -> (a -> t r) -> t r
notify r action = captured $ continue r (Capture . action)
(.:~.) :: Observable t a r -> (a -> t r) -> t r
(.:~.) = notify
follow :: Applicative t => Observable t a r -> (a -> t r) -> t r
follow r action = captured $ continue r (Capture . forever . action)
(.:~*) :: Applicative t => Observable t a r -> (a -> t r) -> t r
(.:~*) = follow
subscribe :: Applicative t => Observable t a r -> (a -> t r) -> t r
subscribe r action = forever $ captured $ continue r (Capture . action)
(*:~.) :: Applicative t => Observable t a r -> (a -> t r) -> t r
(*:~.) = subscribe
watch :: Applicative t => Observable t a r -> (a -> t r) -> t r
watch r action = forever $ captured $ continue r (Capture . forever . action)
(*:~*) :: Applicative t => Observable t a r -> (a -> t r) -> t r
(*:~*) = watch