{-# LANGUAGE RecursiveDo #-}
module Reactive.Threepenny (
Event, Behavior,
Handler, newEvent, register,
currentValue,
module Control.Applicative,
never, filterJust, unionWith,
accumE, apply, stepper,
(<@>), (<@),
filterE, filterApply, whenE, split,
unions, concatenate,
accumB, mapAccum,
Tidings, tidings, facts, rumors,
onChange, unsafeMapIO, newEventsNamed,
) where
import Control.Applicative
import Control.Monad (void)
import Control.Monad.IO.Class
import Data.IORef
import qualified Data.Map as Map
import Reactive.Threepenny.Memo as Memo
import qualified Reactive.Threepenny.PulseLatch as Prim
type Pulse = Prim.Pulse
type Latch = Prim.Latch
type Map = Map.Map
newtype Event a = E { forall a. Event a -> Memo (Pulse a)
unE :: Memo (Pulse a) }
data Behavior a = B { forall a. Behavior a -> Latch a
latch :: Latch a, forall a. Behavior a -> Event ()
changes :: Event () }
type Handler a = a -> IO ()
newEvent :: IO (Event a, Handler a)
newEvent :: forall a. IO (Event a, Handler a)
newEvent = do
(Pulse a
p, Handler a
fire) <- forall a. Build (Pulse a, a -> IO ())
Prim.newPulse
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall {a}. a -> Memo a
fromPure Pulse a
p, Handler a
fire)
newEventsNamed :: Ord name
=> Handler (name, Event a, Handler a)
-> IO (name -> Event a)
newEventsNamed :: forall name a.
Ord name =>
Handler (name, Event a, Handler a) -> IO (name -> Event a)
newEventsNamed Handler (name, Event a, Handler a)
init = do
IORef (Map name (Pulse a))
eventsRef <- forall a. a -> IO (IORef a)
newIORef forall k a. Map k a
Map.empty
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \name
name -> forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall a. IO a -> Memo a
memoize forall a b. (a -> b) -> a -> b
$ do
Map name (Pulse a)
events <- forall a. IORef a -> IO a
readIORef IORef (Map name (Pulse a))
eventsRef
case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup name
name Map name (Pulse a)
events of
Just Pulse a
p -> forall (m :: * -> *) a. Monad m => a -> m a
return Pulse a
p
Maybe (Pulse a)
Nothing -> do
(Pulse a
p, Handler a
fire) <- forall a. Build (Pulse a, a -> IO ())
Prim.newPulse
forall a. IORef a -> a -> IO ()
writeIORef IORef (Map name (Pulse a))
eventsRef forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert name
name Pulse a
p Map name (Pulse a)
events
Handler (name, Event a, Handler a)
init (name
name, forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall {a}. a -> Memo a
fromPure Pulse a
p, Handler a
fire)
forall (m :: * -> *) a. Monad m => a -> m a
return Pulse a
p
register :: Event a -> Handler a -> IO (IO ())
register :: forall a. Event a -> Handler a -> IO (IO ())
register Event a
e Handler a
h = do
Pulse a
p <- forall a. Memo a -> IO a
at (forall a. Event a -> Memo (Pulse a)
unE Event a
e)
forall a. Pulse a -> (a -> IO ()) -> IO (IO ())
Prim.addHandler Pulse a
p Handler a
h
onChange :: Behavior a -> Handler a -> IO ()
onChange :: forall a. Behavior a -> Handler a -> IO ()
onChange (B Latch a
l Event ()
e) Handler a
h = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ do
forall a. Event a -> Handler a -> IO (IO ())
register Event ()
e (\()
_ -> Handler a
h forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Latch a -> Build a
Prim.readLatch Latch a
l)
currentValue :: MonadIO m => Behavior a -> m a
currentValue :: forall (m :: * -> *) a. MonadIO m => Behavior a -> m a
currentValue (B Latch a
l Event ()
_) = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Latch a -> Build a
Prim.readLatch Latch a
l
instance Functor Event where
fmap :: forall a b. (a -> b) -> Event a -> Event b
fmap a -> b
f Event a
e = forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall a b. (a -> IO b) -> Memo a -> Memo b
liftMemo1 (forall a b. (a -> b) -> Pulse a -> Build (Pulse b)
Prim.mapP a -> b
f) (forall a. Event a -> Memo (Pulse a)
unE Event a
e)
unsafeMapIO :: (a -> IO b) -> Event a -> Event b
unsafeMapIO :: forall a b. (a -> IO b) -> Event a -> Event b
unsafeMapIO a -> IO b
f Event a
e = forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall a b. (a -> IO b) -> Memo a -> Memo b
liftMemo1 (forall a b. (a -> IO b) -> Pulse a -> Build (Pulse b)
Prim.unsafeMapIOP a -> IO b
f) (forall a. Event a -> Memo (Pulse a)
unE Event a
e)
never :: Event a
never :: forall a. Event a
never = forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall {a}. a -> Memo a
fromPure forall a. Pulse a
Prim.neverP
filterJust :: Event (Maybe a) -> Event a
filterJust Event (Maybe a)
e = forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall a b. (a -> IO b) -> Memo a -> Memo b
liftMemo1 forall a. Pulse (Maybe a) -> Build (Pulse a)
Prim.filterJustP (forall a. Event a -> Memo (Pulse a)
unE Event (Maybe a)
e)
unionWith :: (a -> a -> a) -> Event a -> Event a -> Event a
unionWith :: forall a. (a -> a -> a) -> Event a -> Event a -> Event a
unionWith a -> a -> a
f Event a
e1 Event a
e2 = forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> IO c) -> Memo a -> Memo b -> Memo c
liftMemo2 (forall a. (a -> a -> a) -> Pulse a -> Pulse a -> Build (Pulse a)
Prim.unionWithP a -> a -> a
f) (forall a. Event a -> Memo (Pulse a)
unE Event a
e1) (forall a. Event a -> Memo (Pulse a)
unE Event a
e2)
apply :: Behavior (a -> b) -> Event a -> Event b
apply :: forall a b. Behavior (a -> b) -> Event a -> Event b
apply Behavior (a -> b)
f Event a
x = forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall a b. (a -> IO b) -> Memo a -> Memo b
liftMemo1 (\Pulse a
p -> forall a b. Latch (a -> b) -> Pulse a -> Build (Pulse b)
Prim.applyP (forall a. Behavior a -> Latch a
latch Behavior (a -> b)
f) Pulse a
p) (forall a. Event a -> Memo (Pulse a)
unE Event a
x)
infixl 4 <@>, <@
(<@>) :: Behavior (a -> b) -> Event a -> Event b
<@> :: forall a b. Behavior (a -> b) -> Event a -> Event b
(<@>) = forall a b. Behavior (a -> b) -> Event a -> Event b
apply
(<@) :: Behavior a -> Event b -> Event a
Behavior a
b <@ :: forall a b. Behavior a -> Event b -> Event a
<@ Event b
e = (forall a b. a -> b -> a
const forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Behavior a
b) forall a b. Behavior (a -> b) -> Event a -> Event b
<@> Event b
e
accumB :: MonadIO m => a -> Event (a -> a) -> m (Behavior a)
accumB :: forall (m :: * -> *) a.
MonadIO m =>
a -> Event (a -> a) -> m (Behavior a)
accumB a
a Event (a -> a)
e = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ do
(Latch a
l1,Pulse a
p1) <- forall a. a -> Pulse (a -> a) -> Build (Latch a, Pulse a)
Prim.accumL a
a forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Memo a -> IO a
at (forall a. Event a -> Memo (Pulse a)
unE Event (a -> a)
e)
Pulse ()
p2 <- forall a b. (a -> b) -> Pulse a -> Build (Pulse b)
Prim.mapP (forall a b. a -> b -> a
const ()) Pulse a
p1
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Latch a -> Event () -> Behavior a
B Latch a
l1 (forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall {a}. a -> Memo a
fromPure Pulse ()
p2)
stepper :: MonadIO m => a -> Event a -> m (Behavior a)
stepper :: forall (m :: * -> *) a. MonadIO m => a -> Event a -> m (Behavior a)
stepper a
a Event a
e = forall (m :: * -> *) a.
MonadIO m =>
a -> Event (a -> a) -> m (Behavior a)
accumB a
a (forall a b. a -> b -> a
const forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event a
e)
accumE :: MonadIO m => a -> Event (a -> a) -> m (Event a)
accumE :: forall (m :: * -> *) a.
MonadIO m =>
a -> Event (a -> a) -> m (Event a)
accumE a
a Event (a -> a)
e = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ do
Pulse a
p <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Pulse (a -> a) -> Build (Latch a, Pulse a)
Prim.accumL a
a forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Memo a -> IO a
at (forall a. Event a -> Memo (Pulse a)
unE Event (a -> a)
e)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Memo (Pulse a) -> Event a
E forall a b. (a -> b) -> a -> b
$ forall {a}. a -> Memo a
fromPure Pulse a
p
instance Functor Behavior where
fmap :: forall a b. (a -> b) -> Behavior a -> Behavior b
fmap a -> b
f ~(B Latch a
l Event ()
e) = forall a. Latch a -> Event () -> Behavior a
B (forall a b. (a -> b) -> Latch a -> Latch b
Prim.mapL a -> b
f Latch a
l) Event ()
e
instance Applicative Behavior where
pure :: forall a. a -> Behavior a
pure a
a = forall a. Latch a -> Event () -> Behavior a
B (forall a. a -> Latch a
Prim.pureL a
a) forall a. Event a
never
~(B Latch (a -> b)
lf Event ()
ef) <*> :: forall a b. Behavior (a -> b) -> Behavior a -> Behavior b
<*> ~(B Latch a
lx Event ()
ex) =
forall a. Latch a -> Event () -> Behavior a
B (forall a b. Latch (a -> b) -> Latch a -> Latch b
Prim.applyL Latch (a -> b)
lf Latch a
lx) (forall a. (a -> a -> a) -> Event a -> Event a -> Event a
unionWith forall a b. a -> b -> a
const Event ()
ef Event ()
ex)
filterE :: (a -> Bool) -> Event a -> Event a
filterE :: forall a. (a -> Bool) -> Event a -> Event a
filterE a -> Bool
p = forall {a}. Event (Maybe a) -> Event a
filterJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\a
a -> if a -> Bool
p a
a then forall a. a -> Maybe a
Just a
a else forall a. Maybe a
Nothing)
filterApply :: Behavior (a -> Bool) -> Event a -> Event a
filterApply :: forall a. Behavior (a -> Bool) -> Event a -> Event a
filterApply Behavior (a -> Bool)
bp = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> Event a -> Event a
filterE forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Behavior (a -> b) -> Event a -> Event b
apply ((\a -> Bool
p a
a -> (a -> Bool
p a
a,a
a)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Behavior (a -> Bool)
bp)
whenE :: Behavior Bool -> Event a -> Event a
whenE :: forall a. Behavior Bool -> Event a -> Event a
whenE Behavior Bool
bf = forall a. Behavior (a -> Bool) -> Event a -> Event a
filterApply (forall a b. a -> b -> a
const forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Behavior Bool
bf)
split :: Event (Either a b) -> (Event a, Event b)
split :: forall a b. Event (Either a b) -> (Event a, Event b)
split Event (Either a b)
e = (forall {a}. Event (Maybe a) -> Event a
filterJust forall a b. (a -> b) -> a -> b
$ forall {a} {b}. Either a b -> Maybe a
fromLeft forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event (Either a b)
e, forall {a}. Event (Maybe a) -> Event a
filterJust forall a b. (a -> b) -> a -> b
$ forall {a} {a}. Either a a -> Maybe a
fromRight forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event (Either a b)
e)
where
fromLeft :: Either a b -> Maybe a
fromLeft (Left a
a) = forall a. a -> Maybe a
Just a
a
fromLeft (Right b
b) = forall a. Maybe a
Nothing
fromRight :: Either a a -> Maybe a
fromRight (Left a
a) = forall a. Maybe a
Nothing
fromRight (Right a
b) = forall a. a -> Maybe a
Just a
b
unions :: [Event a] -> Event [a]
unions :: forall a. [Event a] -> Event [a]
unions = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (forall a. (a -> a -> a) -> Event a -> Event a -> Event a
unionWith forall a. [a] -> [a] -> [a]
(++)) forall a. Event a
never forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. a -> [a] -> [a]
:[]))
concatenate :: [a -> a] -> (a -> a)
concatenate :: forall a. [a -> a] -> a -> a
concatenate = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) forall a. a -> a
id
mapAccum :: MonadIO m => acc -> Event (acc -> (x,acc)) -> m (Event x, Behavior acc)
mapAccum :: forall (m :: * -> *) acc x.
MonadIO m =>
acc -> Event (acc -> (x, acc)) -> m (Event x, Behavior acc)
mapAccum acc
acc Event (acc -> (x, acc))
ef = do
Event (x, acc)
e <- forall (m :: * -> *) a.
MonadIO m =>
a -> Event (a -> a) -> m (Event a)
accumE (forall a. HasCallStack => a
undefined,acc
acc) ((forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event (acc -> (x, acc))
ef)
Behavior acc
b <- forall (m :: * -> *) a. MonadIO m => a -> Event a -> m (Behavior a)
stepper acc
acc (forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event (x, acc)
e)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event (x, acc)
e, Behavior acc
b)
data Tidings a = T { forall a. Tidings a -> Behavior a
facts :: Behavior a, forall a. Tidings a -> Event a
rumors :: Event a }
tidings :: Behavior a -> Event a -> Tidings a
tidings :: forall a. Behavior a -> Event a -> Tidings a
tidings Behavior a
b Event a
e = forall a. Behavior a -> Event a -> Tidings a
T Behavior a
b Event a
e
instance Functor Tidings where
fmap :: forall a b. (a -> b) -> Tidings a -> Tidings b
fmap a -> b
f (T Behavior a
b Event a
e) = forall a. Behavior a -> Event a -> Tidings a
T (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Behavior a
b) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Event a
e)
instance Applicative Tidings where
pure :: forall a. a -> Tidings a
pure a
x = forall a. Behavior a -> Event a -> Tidings a
T (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x) forall a. Event a
never
Tidings (a -> b)
f <*> :: forall a b. Tidings (a -> b) -> Tidings a -> Tidings b
<*> Tidings a
x = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a b. (a -> b) -> a -> b
($) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. Tidings a -> Tidings b -> Tidings (a, b)
pair Tidings (a -> b)
f Tidings a
x
pair :: Tidings a -> Tidings b -> Tidings (a,b)
pair :: forall a b. Tidings a -> Tidings b -> Tidings (a, b)
pair (T Behavior a
bx Event a
ex) (T Behavior b
by Event b
ey) = forall a. Behavior a -> Event a -> Tidings a
T Behavior (a, b)
b Event (a, b)
e
where
b :: Behavior (a, b)
b = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Behavior a
bx forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Behavior b
by
x :: Event (a, b)
x = forall a b c. (a -> b -> c) -> b -> a -> c
flip (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Behavior b
by forall a b. Behavior (a -> b) -> Event a -> Event b
<@> Event a
ex
y :: Event (a, b)
y = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Behavior a
bx forall a b. Behavior (a -> b) -> Event a -> Event b
<@> Event b
ey
e :: Event (a, b)
e = forall a. (a -> a -> a) -> Event a -> Event a -> Event a
unionWith (\(a
x,b
_) (a
_,b
y) -> (a
x,b
y)) Event (a, b)
x Event (a, b)
y
test :: IO (Int -> IO ())
test :: IO (Int -> IO ())
test = do
(Event Int
e1,Int -> IO ()
fire) <- forall a. IO (Event a, Handler a)
newEvent
Event Int
e2 <- forall (m :: * -> *) a.
MonadIO m =>
a -> Event (a -> a) -> m (Event a)
accumE Int
0 forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a -> a
(+) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event Int
e1
IO ()
_ <- forall a. Event a -> Handler a -> IO (IO ())
register Event Int
e2 forall a. Show a => a -> IO ()
print
forall (m :: * -> *) a. Monad m => a -> m a
return Int -> IO ()
fire
test_recursion1 :: IO (IO ())
test_recursion1 :: IO (IO ())
test_recursion1 = mdo
(Event ()
e1, () -> IO ()
fire) <- forall a. IO (Event a, Handler a)
newEvent
let e2 :: Event Int
e2 :: Event Int
e2 = forall a b. Behavior (a -> b) -> Event a -> Event b
apply (forall a b. a -> b -> a
const forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Behavior Int
b) Event ()
e1
Behavior Int
b <- forall (m :: * -> *) a.
MonadIO m =>
a -> Event (a -> a) -> m (Behavior a)
accumB Int
0 forall a b. (a -> b) -> a -> b
$ (forall a. Num a => a -> a -> a
+Int
1) forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Event Int
e2
IO ()
_ <- forall a. Event a -> Handler a -> IO (IO ())
register Event Int
e2 forall a. Show a => a -> IO ()
print
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ () -> IO ()
fire ()