{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
#ifdef USE_REFLEX_OPTIMIZER
{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
#endif
module Reflex.Dynamic.Uniq
( UniqDynamic
, uniqDynamic
, fromUniqDynamic
, alreadyUniqDynamic
) where
import Control.Applicative (Applicative (..))
import GHC.Exts
import Reflex.Class
newtype UniqDynamic t a = UniqDynamic { forall t a. UniqDynamic t a -> Dynamic t a
unUniqDynamic :: Dynamic t a }
uniqDynamic :: Reflex t => Dynamic t a -> UniqDynamic t a
uniqDynamic :: forall t a. Reflex t => Dynamic t a -> UniqDynamic t a
uniqDynamic Dynamic t a
d = Dynamic t a -> UniqDynamic t a
forall t a. Dynamic t a -> UniqDynamic t a
UniqDynamic (Dynamic t a -> UniqDynamic t a) -> Dynamic t a -> UniqDynamic t a
forall a b. (a -> b) -> a -> b
$ PullM t a -> Event t a -> Dynamic t a
forall a. PullM t a -> Event t a -> Dynamic t a
forall {k} (t :: k) a.
Reflex t =>
PullM t a -> Event t a -> Dynamic t a
unsafeBuildDynamic (Behavior t a -> PullM t a
forall a. Behavior t a -> PullM t a
forall {k} (t :: k) (m :: * -> *) a.
MonadSample t m =>
Behavior t a -> m a
sample (Behavior t a -> PullM t a) -> Behavior t a -> PullM t a
forall a b. (a -> b) -> a -> b
$ Dynamic t a -> Behavior t a
forall a. Dynamic t a -> Behavior t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t a
d) (Event t a -> Dynamic t a) -> Event t a -> Dynamic t a
forall a b. (a -> b) -> a -> b
$ ((a -> PushM t (Maybe a)) -> Event t a -> Event t a)
-> Event t a -> (a -> PushM t (Maybe a)) -> Event t a
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> PushM t (Maybe a)) -> Event t a -> Event t a
forall {k} (t :: k) a b.
Reflex t =>
(a -> PushM t (Maybe b)) -> Event t a -> Event t b
forall a b. (a -> PushM t (Maybe b)) -> Event t a -> Event t b
pushCheap (Dynamic t a -> Event t a
forall a. Dynamic t a -> Event t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Event t a
updated Dynamic t a
d) ((a -> PushM t (Maybe a)) -> Event t a)
-> (a -> PushM t (Maybe a)) -> Event t a
forall a b. (a -> b) -> a -> b
$ \a
new -> do
a
old <- Behavior t a -> PushM t a
forall a. Behavior t a -> PushM t a
forall {k} (t :: k) (m :: * -> *) a.
MonadSample t m =>
Behavior t a -> m a
sample (Behavior t a -> PushM t a) -> Behavior t a -> PushM t a
forall a b. (a -> b) -> a -> b
$ Dynamic t a -> Behavior t a
forall a. Dynamic t a -> Behavior t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t a
d
Maybe a -> PushM t (Maybe a)
forall a. a -> PushM t a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> PushM t (Maybe a)) -> Maybe a -> PushM t (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> a -> Maybe a
forall a. a -> a -> Maybe a
unsafeJustChanged a
old a
new
fromUniqDynamic :: (Reflex t, Eq a) => UniqDynamic t a -> Dynamic t a
fromUniqDynamic :: forall t a. (Reflex t, Eq a) => UniqDynamic t a -> Dynamic t a
fromUniqDynamic (UniqDynamic Dynamic t a
d) = Behavior t a -> Event t a -> Dynamic t a
forall {k} (t :: k) a.
Reflex t =>
Behavior t a -> Event t a -> Dynamic t a
unsafeDynamic (Dynamic t a -> Behavior t a
forall a. Dynamic t a -> Behavior t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t a
d) Event t a
e'
where
superEq :: a -> a -> Bool
superEq a
a a
b = a
a a -> a -> Bool
forall a. a -> a -> Bool
`unsafePtrEq` a
b Bool -> Bool -> Bool
|| a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
b
e' :: Event t a
e' = (a -> a -> Maybe a) -> Behavior t a -> Event t a -> Event t a
forall {k} (t :: k) a b c.
Reflex t =>
(a -> b -> Maybe c) -> Behavior t a -> Event t b -> Event t c
attachWithMaybe (\a
x a
x' -> if a
x' a -> a -> Bool
forall a. Eq a => a -> a -> Bool
`superEq` a
x then Maybe a
forall a. Maybe a
Nothing else a -> Maybe a
forall a. a -> Maybe a
Just a
x') (Dynamic t a -> Behavior t a
forall a. Dynamic t a -> Behavior t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t a
d) (Dynamic t a -> Event t a
forall a. Dynamic t a -> Event t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Event t a
updated Dynamic t a
d)
alreadyUniqDynamic :: Dynamic t a -> UniqDynamic t a
alreadyUniqDynamic :: forall t a. Dynamic t a -> UniqDynamic t a
alreadyUniqDynamic = Dynamic t a -> UniqDynamic t a
forall t a. Dynamic t a -> UniqDynamic t a
UniqDynamic
unsafePtrEq :: a -> a -> Bool
unsafePtrEq :: forall a. a -> a -> Bool
unsafePtrEq a
a a
b = case a
a a -> Int# -> Int#
forall a b. a -> b -> b
`seq` a
b a -> Int# -> Int#
forall a b. a -> b -> b
`seq` a -> a -> Int#
forall a b. a -> b -> Int#
reallyUnsafePtrEquality# a
a a
b of
Int#
0# -> Bool
False
Int#
_ -> Bool
True
unsafeJustChanged :: a -> a -> Maybe a
unsafeJustChanged :: forall a. a -> a -> Maybe a
unsafeJustChanged a
old a
new =
if a
old a -> a -> Bool
forall a. a -> a -> Bool
`unsafePtrEq` a
new
then Maybe a
forall a. Maybe a
Nothing
else a -> Maybe a
forall a. a -> Maybe a
Just a
new
instance Reflex t => Accumulator t (UniqDynamic t) where
accumMaybeM :: forall (m :: * -> *) a b.
(MonadHold t m, MonadFix m) =>
(a -> b -> PushM t (Maybe a))
-> a -> Event t b -> m (UniqDynamic t a)
accumMaybeM a -> b -> PushM t (Maybe a)
f a
z Event t b
e = do
let f' :: a -> b -> PushM t (Maybe a)
f' a
old b
change = do
Maybe a
mNew <- a -> b -> PushM t (Maybe a)
f a
old b
change
Maybe a -> PushM t (Maybe a)
forall a. a -> PushM t a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> PushM t (Maybe a)) -> Maybe a -> PushM t (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> a -> Maybe a
forall a. a -> a -> Maybe a
unsafeJustChanged a
old (a -> Maybe a) -> Maybe a -> Maybe a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe a
mNew
Dynamic t a
d <- (a -> b -> PushM t (Maybe a)) -> a -> Event t b -> m (Dynamic t a)
forall {k} (t :: k) (m :: * -> *) a b.
(Reflex t, MonadHold t m, MonadFix m) =>
(a -> b -> PushM t (Maybe a)) -> a -> Event t b -> m (Dynamic t a)
accumMaybeMDyn a -> b -> PushM t (Maybe a)
f' a
z Event t b
e
UniqDynamic t a -> m (UniqDynamic t a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (UniqDynamic t a -> m (UniqDynamic t a))
-> UniqDynamic t a -> m (UniqDynamic t a)
forall a b. (a -> b) -> a -> b
$ Dynamic t a -> UniqDynamic t a
forall t a. Dynamic t a -> UniqDynamic t a
UniqDynamic Dynamic t a
d
mapAccumMaybeM :: forall (m :: * -> *) a b c.
(MonadHold t m, MonadFix m) =>
(a -> b -> PushM t (Maybe a, Maybe c))
-> a -> Event t b -> m (UniqDynamic t a, Event t c)
mapAccumMaybeM a -> b -> PushM t (Maybe a, Maybe c)
f a
z Event t b
e = do
let f' :: a -> b -> PushM t (Maybe a, Maybe c)
f' a
old b
change = do
(Maybe a
mNew, Maybe c
output) <- a -> b -> PushM t (Maybe a, Maybe c)
f a
old b
change
(Maybe a, Maybe c) -> PushM t (Maybe a, Maybe c)
forall a. a -> PushM t a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> a -> Maybe a
forall a. a -> a -> Maybe a
unsafeJustChanged a
old (a -> Maybe a) -> Maybe a -> Maybe a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe a
mNew, Maybe c
output)
(Dynamic t a
d, Event t c
out) <- (a -> b -> PushM t (Maybe a, Maybe c))
-> a -> Event t b -> m (Dynamic t a, Event t c)
forall {k} (t :: k) (m :: * -> *) a b c.
(Reflex t, MonadHold t m, MonadFix m) =>
(a -> b -> PushM t (Maybe a, Maybe c))
-> a -> Event t b -> m (Dynamic t a, Event t c)
mapAccumMaybeMDyn a -> b -> PushM t (Maybe a, Maybe c)
f' a
z Event t b
e
(UniqDynamic t a, Event t c) -> m (UniqDynamic t a, Event t c)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Dynamic t a -> UniqDynamic t a
forall t a. Dynamic t a -> UniqDynamic t a
UniqDynamic Dynamic t a
d, Event t c
out)
instance Reflex t => Functor (UniqDynamic t) where
fmap :: forall a b. (a -> b) -> UniqDynamic t a -> UniqDynamic t b
fmap a -> b
f (UniqDynamic Dynamic t a
d) = Dynamic t b -> UniqDynamic t b
forall t a. Reflex t => Dynamic t a -> UniqDynamic t a
uniqDynamic (Dynamic t b -> UniqDynamic t b) -> Dynamic t b -> UniqDynamic t b
forall a b. (a -> b) -> a -> b
$ (a -> b) -> Dynamic t a -> Dynamic t b
forall a b. (a -> b) -> Dynamic t a -> Dynamic t b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Dynamic t a
d
instance Reflex t => Applicative (UniqDynamic t) where
pure :: forall a. a -> UniqDynamic t a
pure = Dynamic t a -> UniqDynamic t a
forall t a. Dynamic t a -> UniqDynamic t a
UniqDynamic (Dynamic t a -> UniqDynamic t a)
-> (a -> Dynamic t a) -> a -> UniqDynamic t a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Dynamic t a
forall {k} (t :: k) a. Reflex t => a -> Dynamic t a
constDyn
UniqDynamic Dynamic t (a -> b)
a <*> :: forall a b.
UniqDynamic t (a -> b) -> UniqDynamic t a -> UniqDynamic t b
<*> UniqDynamic Dynamic t a
b = Dynamic t b -> UniqDynamic t b
forall t a. Reflex t => Dynamic t a -> UniqDynamic t a
uniqDynamic (Dynamic t b -> UniqDynamic t b) -> Dynamic t b -> UniqDynamic t b
forall a b. (a -> b) -> a -> b
$ Dynamic t (a -> b)
a Dynamic t (a -> b) -> Dynamic t a -> Dynamic t b
forall a b. Dynamic t (a -> b) -> Dynamic t a -> Dynamic t b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Dynamic t a
b
UniqDynamic t a
_ *> :: forall a b. UniqDynamic t a -> UniqDynamic t b -> UniqDynamic t b
*> UniqDynamic t b
b = UniqDynamic t b
b
UniqDynamic t a
a <* :: forall a b. UniqDynamic t a -> UniqDynamic t b -> UniqDynamic t a
<* UniqDynamic t b
_ = UniqDynamic t a
a
instance Reflex t => Monad (UniqDynamic t) where
UniqDynamic Dynamic t a
x >>= :: forall a b.
UniqDynamic t a -> (a -> UniqDynamic t b) -> UniqDynamic t b
>>= a -> UniqDynamic t b
f = Dynamic t b -> UniqDynamic t b
forall t a. Reflex t => Dynamic t a -> UniqDynamic t a
uniqDynamic (Dynamic t b -> UniqDynamic t b) -> Dynamic t b -> UniqDynamic t b
forall a b. (a -> b) -> a -> b
$ Dynamic t a
x Dynamic t a -> (a -> Dynamic t b) -> Dynamic t b
forall a b. Dynamic t a -> (a -> Dynamic t b) -> Dynamic t b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= UniqDynamic t b -> Dynamic t b
forall t a. UniqDynamic t a -> Dynamic t a
unUniqDynamic (UniqDynamic t b -> Dynamic t b)
-> (a -> UniqDynamic t b) -> a -> Dynamic t b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> UniqDynamic t b
f
UniqDynamic t a
_ >> :: forall a b. UniqDynamic t a -> UniqDynamic t b -> UniqDynamic t b
>> UniqDynamic t b
b = UniqDynamic t b
b
return :: forall a. a -> UniqDynamic t a
return = a -> UniqDynamic t a
forall a. a -> UniqDynamic t a
forall (f :: * -> *) a. Applicative f => a -> f a
pure