@@ -9,7 +9,6 @@
99{-# LANGUAGE GADTs #-}
1010{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1111{-# LANGUAGE LambdaCase #-}
12−{-# LANGUAGE MultiParamTypeClasses #-}
1312{-# LANGUAGE MultiWayIf #-}
1413{-# LANGUAGE RankNTypes #-}
1514{-# LANGUAGE RoleAnnotations #-}
@@ -17,9 +16,15 @@
1716{-# LANGUAGE TypeFamilies #-}
1817{-# LANGUAGE TypeOperators #-}
1918{-# LANGUAGE UndecidableInstances #-}
19+{-# LANGUAGE PolyKinds #-}
20+{-# LANGUAGE DeriveFunctor #-}
21+{-# LANGUAGE StandaloneDeriving #-}
22+{-# LANGUAGE InstanceSigs #-}
23+
2024#ifdef USE_REFLEX_OPTIMIZER
2125{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
2226#endif
27+{-# OPTIONS_GHC -Wunused-binds #-}
2328-- | This module is the implementation of the 'Spider' 'Reflex' engine. It uses
2429-- a graph traversal algorithm to propagate 'Event's and 'Behavior's.
2530module Reflex.Spider.Internal (module Reflex.Spider.Internal) where
@@ -33,7 +38,10 @@ import Control.Monad hiding (forM, forM_, mapM, mapM_)
3338import Control.Monad.Exception
3439import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
3540import Control.Monad.Primitive
36−import Control.Monad.Reader hiding (forM, forM_, mapM, mapM_)
41+--import Control.Monad.Reader hiding (forM, forM_, mapM, mapM_)
42+import Control.Monad.Reader.Class
43+import Control.Monad.IO.Class
44+import Control.Monad.ReaderIO
3745import Control.Monad.Ref
3846import Data.Align
3947import Data.Coerce
@@ -49,20 +57,27 @@ import Data.GADT.Compare
4957import Data.IntMap.Strict (IntMap)
5058import qualified Data.IntMap.Strict as IntMap
5159import Data.IORef
52−import Data.Maybe
60+import Data.Kind (Type)
61+import Data.Maybe hiding (mapMaybe)
5362import Data.Monoid ((<>))
5463import Data.Proxy
5564import Data.These
5665import Data.Traversable
66+import Data.Witherable (Filterable, mapMaybe)
5767import GHC.Exts
5868import GHC.IORef (IORef (..))
5969import GHC.Stack
6070import Reflex.FastWeak
61−import Reflex.FunctorMaybe
6271import System.IO.Unsafe
6372import System.Mem.Weak
6473import Unsafe.Coerce
6574
75+#if defined(MIN_VERSION_semialign)
76+#if MIN_VERSION_these(0,8,0)
77+import Data.These.Combinators (justThese)
78+#endif
79+#endif
80+
6681#ifdef DEBUG_CYCLES
6782import Control.Monad.State hiding (forM, forM_, mapM, mapM_, sequence)
6883import Data.List.NonEmpty (NonEmpty (..), nonEmpty)
@@ -74,9 +89,9 @@ import Data.Tree (Forest, Tree (..), drawForest)
7489import Data.FastWeakBag (FastWeakBag)
7590import qualified Data.FastWeakBag as FastWeakBag
7691import Data.Reflection
77−import Data.Some (Some)
78−import qualified Data.Some as Some
92+import Data.Some (Some(Some))
7993import Data.Type.Coercion
94+import Data.Profunctor.Unsafe ((#.), (.#))
8095import Data.WeakBag (WeakBag, WeakBagTicket, _weakBag_children)
8196import qualified Data.WeakBag as WeakBag
8297import qualified Reflex.Class
@@ -193,12 +208,6 @@ nextNodeIdRef = unsafePerformIO $ newIORef 1
193208
194209newNodeId :: IO Int
195210newNodeId = atomicModifyIORef' nextNodeIdRef $ \n -> (succ n, n)
196−
197−{-# NOINLINE unsafeNodeId #-}
198−unsafeNodeId :: a -> Int
199−unsafeNodeId a = unsafePerformIO $ do
200− touch a
201− newNodeId
202211#endif
203212
204213--------------------------------------------------------------------------------
@@ -302,9 +311,10 @@ cacheEvent e =
302311#else
303312 Event $
304313#endif
305− let mSubscribedRef :: IORef (FastWeak (CacheSubscribed x a))
306− !mSubscribedRef = unsafeNewIORef e emptyFastWeak
307− in \sub -> {-# SCC "cacheEvent" #-} do
314+ unsafePerformIO $ do
315+ mSubscribedRef :: IORef (FastWeak (CacheSubscribed x a))
316+ <- newIORef emptyFastWeak
317+ pure $ \sub -> {-# SCC "cacheEvent" #-} do
308318#ifdef DEBUG_TRACE_EVENTS
309319 unless (BS8.null callSite) $ liftIO $ BS8.hPutStrLn stderr callSite
310320#endif
@@ -370,7 +380,7 @@ eventRoot !k !r = Event $ wrap eventSubscribedRoot $ liftIO . getRootSubscribed
370380eventNever :: Event x a
371381eventNever = Event $ \_ -> return (EventSubscription (return ()) eventSubscribedNever, Nothing)
372382
373−eventFan :: (GCompare k, HasSpiderTimeline x) => k a -> Fan x k -> Event x a
383+eventFan :: (GCompare k, HasSpiderTimeline x) => k a -> Fan x k v -> Event x (v a)
374384eventFan !k !f = Event $ wrap eventSubscribedFan $ getFanSubscribed k f
375385
376386eventSwitch :: HasSpiderTimeline x => Switch x a -> Event x a
@@ -422,14 +432,14 @@ newSubscriberHold h = return $ Subscriber
422432 , subscriberRecalculateHeight = \_ -> return ()
423433 }
424434
425−newSubscriberFan :: forall x k. (HasSpiderTimeline x, GCompare k) => FanSubscribed x k -> IO (Subscriber x (DMap k Identity))
435+newSubscriberFan :: forall x k v. (HasSpiderTimeline x, GCompare k) => FanSubscribed x k v -> IO (Subscriber x (DMap k v))
426436newSubscriberFan subscribed = return $ Subscriber
427437 { subscriberPropagate = \a -> {-# SCC "traverseFan" #-} do
428438 subs <- liftIO $ readIORef $ fanSubscribedSubscribers subscribed
429439 tracePropagate (Proxy :: Proxy x) $ "SubscriberFan" <> showNodeId subscribed <> ": " ++ show (DMap.size subs) ++ " keys subscribed, " ++ show (DMap.size a) ++ " keys firing"
430440 liftIO $ writeIORef (fanSubscribedOccurrence subscribed) $ Just a
431441 scheduleClear $ fanSubscribedOccurrence subscribed
432− let f _ (Pair (Identity v) subsubs) = do
442+ let f _ (Pair v subsubs) = do
433443 propagate v $ _fanSubscribedChildren_list subsubs
434444 return $ Constant ()
435445 _ <- DMap.traverseWithKey f $ DMap.intersectionWithKey (\_ -> Pair) a subs --TODO: Would be nice to have DMap.traverse_
@@ -545,6 +555,11 @@ propagateFast a subscribers = withIncreasedDepth $ do
545555toAny :: a -> Any
546556toAny = unsafeCoerce
547557
558+-- Why do we use Any here, instead of just giving eventSubscribedRetained an
559+-- existential type? Sadly, GHC does not currently know how to unbox types
560+-- with existentially quantified fields. So instead we just coerce values
561+-- to type Any on the way in. Since we never coerce them back, this is
562+-- perfectly safe.
548563data EventSubscribed x = EventSubscribed
549564 { eventSubscribedHeightRef :: {-# UNPACK #-} !(IORef Height)
550565 , eventSubscribedRetained :: {-# NOUNPACK #-} !Any
@@ -577,12 +592,12 @@ eventSubscribedNever = EventSubscribed
577592#endif
578593 }
579594
580−eventSubscribedFan :: FanSubscribed x k -> EventSubscribed x
595+eventSubscribedFan :: FanSubscribed x k v -> EventSubscribed x
581596eventSubscribedFan !subscribed = EventSubscribed
582597 { eventSubscribedHeightRef = eventSubscribedHeightRef $ _eventSubscription_subscribed $ fanSubscribedParent subscribed
583598 , eventSubscribedRetained = toAny subscribed
584599#ifdef DEBUG_CYCLES
585− , eventSubscribedGetParents = return [Some.This $ _eventSubscription_subscribed $ fanSubscribedParent subscribed]
600+ , eventSubscribedGetParents = return [Some $ _eventSubscription_subscribed $ fanSubscribedParent subscribed]
586601 , eventSubscribedHasOwnHeightRef = False
587602 , eventSubscribedWhoCreated = whoCreatedIORef $ fanSubscribedCachedSubscribed subscribed
588603#endif
@@ -595,7 +610,7 @@ eventSubscribedSwitch !subscribed = EventSubscribed
595610#ifdef DEBUG_CYCLES
596611 , eventSubscribedGetParents = do
597612 s <- readIORef $ switchSubscribedCurrentParent subscribed
598− return [Some.This $ _eventSubscription_subscribed s]
613+ return [Some $ _eventSubscription_subscribed s]
599614 , eventSubscribedHasOwnHeightRef = True
600615 , eventSubscribedWhoCreated = whoCreatedIORef $ switchSubscribedCachedSubscribed subscribed
601616#endif
@@ -608,8 +623,8 @@ eventSubscribedCoincidence !subscribed = EventSubscribed
608623#ifdef DEBUG_CYCLES
609624 , eventSubscribedGetParents = do
610625 innerSubscription <- readIORef $ coincidenceSubscribedInnerParent subscribed
611− let outerParent = Some.This $ _eventSubscription_subscribed $ coincidenceSubscribedOuterParent subscribed
612− innerParents = maybeToList $ fmap Some.This innerSubscription
626+ let outerParent = Some $ _eventSubscription_subscribed $ coincidenceSubscribedOuterParent subscribed
627+ innerParents = maybeToList $ fmap Some innerSubscription
613628 return $ outerParent : innerParents
614629 , eventSubscribedHasOwnHeightRef = True
615630 , eventSubscribedWhoCreated = whoCreatedIORef $ coincidenceSubscribedCachedSubscribed subscribed
@@ -625,13 +640,13 @@ whoCreatedEventSubscribed = eventSubscribedWhoCreated
625640
626641walkInvalidHeightParents :: EventSubscribed x -> IO [Some (EventSubscribed x)]
627642walkInvalidHeightParents s0 = do
628− subscribers <- flip execStateT mempty $ ($ Some.This s0) $ fix $ \loop (Some.This s) -> do
643+ subscribers <- flip execStateT mempty $ ($ Some s0) $ fix $ \loop (Some s) -> do
629644 h <- liftIO $ readIORef $ eventSubscribedHeightRef s
630645 when (h == invalidHeight) $ do
631646 when (eventSubscribedHasOwnHeightRef s) $ liftIO $ writeIORef (eventSubscribedHeightRef s) $! invalidHeightBeingTraversed
632− modify (Some.This s :)
647+ modify (Some s :)
633648 mapM_ loop =<< liftIO (eventSubscribedGetParents s)
634− forM_ subscribers $ \(Some.This s) -> writeIORef (eventSubscribedHeightRef s) $! invalidHeight
649+ forM_ subscribers $ \(Some s) -> writeIORef (eventSubscribedHeightRef s) $! invalidHeight
635650 return subscribers
636651#endif
637652
@@ -659,7 +674,7 @@ behaviorPull !p = Behavior $ do
659674 val <- liftIO $ readIORef $ pullValue p
660675 case val of
661676 Just subscribed -> do
662− askParentsRef >>= mapM_ (\r -> liftIO $ modifyIORef' r (SomeBehaviorSubscribed (BehaviorSubscribedPull subscribed) :))
677+ askParentsRef >>= mapM_ (\r -> liftIO $ modifyIORef' r (SomeBehaviorSubscribed (Some (BehaviorSubscribedPull subscribed)) :))
663678 askInvalidator >>= mapM_ (\wi -> liftIO $ modifyIORef' (pullSubscribedInvalidators subscribed) (wi:))
664679 liftIO $ touch $ pullSubscribedOwnInvalidator subscribed
665680 return $ pullSubscribedValue subscribed
@@ -668,7 +683,7 @@ behaviorPull !p = Behavior $ do
668683 wi <- liftIO $ mkWeakPtrWithDebug i "InvalidatorPull"
669684 parentsRef <- liftIO $ newIORef []
670685 holdInits <- askBehaviorHoldInits
671− a <- liftIO $ runReaderT (unBehaviorM $ pullCompute p) (Just (wi, parentsRef), holdInits)
686+ a <- liftIO $ runReaderIO (unBehaviorM $ pullCompute p) (Just (wi, parentsRef), holdInits)
672687 invsRef <- liftIO . newIORef . maybeToList =<< askInvalidator
673688 parents <- liftIO $ readIORef parentsRef
674689 let subscribed = PullSubscribed
@@ -678,7 +693,7 @@ behaviorPull !p = Behavior $ do
678693 , pullSubscribedParents = parents
679694 }
680695 liftIO $ writeIORef (pullValue p) $ Just subscribed
681− askParentsRef >>= mapM_ (\r -> liftIO $ modifyIORef' r (SomeBehaviorSubscribed (BehaviorSubscribedPull subscribed) :))
696+ askParentsRef >>= mapM_ (\r -> liftIO $ modifyIORef' r (SomeBehaviorSubscribed (Some (BehaviorSubscribedPull subscribed)) :))
682697 return a
683698
684699behaviorDyn :: Patch p => Dyn x p -> Behavior x (PatchTarget p)
@@ -689,7 +704,7 @@ readHoldTracked :: Hold x p -> BehaviorM x (PatchTarget p)
689704readHoldTracked h = do
690705 result <- liftIO $ readIORef $ holdValue h
691706 askInvalidator >>= mapM_ (\wi -> liftIO $ modifyIORef' (holdInvalidators h) (wi:))
692− askParentsRef >>= mapM_ (\r -> liftIO $ modifyIORef' r (SomeBehaviorSubscribed (BehaviorSubscribedHold h) :))
707+ askParentsRef >>= mapM_ (\r -> liftIO $ modifyIORef' r (SomeBehaviorSubscribed (Some (BehaviorSubscribedHold h)) :))
693708 liftIO $ touch h -- Otherwise, if this gets inlined enough, the hold's parent reference may get collected
694709 return result
695710
@@ -703,42 +718,46 @@ readBehaviorUntracked b = do
703718-- Dynamic
704719--------------------------------------------------------------------------------
705720
706−data Dynamic x p = Dynamic
707− { dynamicCurrent :: !(Behavior x (PatchTarget p))
708− , dynamicUpdated :: !(Event x p)
721+type DynamicS x p = Dynamic x (PatchTarget p) p
722+
723+data Dynamic x target p = Dynamic
724+ { dynamicCurrent :: !(Behavior x target)
725+ , dynamicUpdated :: Event x p -- This must be lazy; see the comment on holdEvent --TODO: Would this let us eliminate `Dyn`?
709726 }
710727
711−dynamicHold :: Hold x p -> Dynamic x p
728+deriving instance (HasSpiderTimeline x) => Functor (Dynamic x target)
729+
730+
731+
732+
733+dynamicHold :: Hold x p -> DynamicS x p
712734dynamicHold !h = Dynamic
713735 { dynamicCurrent = behaviorHold h
714736 , dynamicUpdated = eventHold h
715737 }
716738
717−dynamicHoldIdentity :: Hold x (Identity a) -> Dynamic x (Identity a)
739+dynamicHoldIdentity :: Hold x (Identity a) -> DynamicS x (Identity a)
718740dynamicHoldIdentity = dynamicHold
719741
720−dynamicConst :: PatchTarget p -> Dynamic x p
742+dynamicConst :: PatchTarget p -> DynamicS x p
721743dynamicConst !a = Dynamic
722744 { dynamicCurrent = behaviorConst a
723745 , dynamicUpdated = eventNever
724746 }
725747
726−dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> Dynamic x p
748+dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> DynamicS x p
727749dynamicDyn !d = Dynamic
728750 { dynamicCurrent = behaviorDyn d
729751 , dynamicUpdated = eventDyn d
730752 }
731753
732−dynamicDynIdentity :: HasSpiderTimeline x => Dyn x (Identity a) -> Dynamic x (Identity a)
754+dynamicDynIdentity :: HasSpiderTimeline x => Dyn x (Identity a) -> DynamicS x (Identity a)
733755dynamicDynIdentity = dynamicDyn
734756
735757--------------------------------------------------------------------------------
736758-- Combinators
737759--------------------------------------------------------------------------------
738760
739−--TODO: Figure out why certain things are not 'representational', then make them
740−--representational so we can use coerce
741−
742761--type role Hold representational
743762data Hold x p
744763 = Hold { holdValue :: !(IORef (PatchTarget p))
@@ -759,20 +778,25 @@ globalSpiderTimelineEnv = unsafePerformIO unsafeNewSpiderTimelineEnv
759778
760779-- | Stores all global data relevant to a particular Spider timeline; only one
761780-- value should exist for each type @x@
762−data SpiderTimelineEnv x = SpiderTimelineEnv
781+newtype SpiderTimelineEnv x = STE {unSTE :: SpiderTimelineEnv' x}
782+-- We implement SpiderTimelineEnv with a newtype wrapper so
783+-- we can get the coercions we want safely.
784+type role SpiderTimelineEnv nominal
785+
786+data SpiderTimelineEnv' x = SpiderTimelineEnv
763787 { _spiderTimeline_lock :: {-# UNPACK #-} !(MVar ())
764788 , _spiderTimeline_eventEnv :: {-# UNPACK #-} !(EventEnv x)
765789#ifdef DEBUG
766790 , _spiderTimeline_depth :: {-# UNPACK #-} !(IORef Int)
767791#endif
768792 }
769−type role SpiderTimelineEnv nominal
793+type role SpiderTimelineEnv' phantom
770794
771795instance Eq (SpiderTimelineEnv x) where
772796 _ == _ = True -- Since only one exists of each type
773797
774798instance GEq SpiderTimelineEnv where
775− a `geq` b = if _spiderTimeline_lock a == _spiderTimeline_lock b
799+ a `geq` b = if _spiderTimeline_lock (unSTE a) == _spiderTimeline_lock (unSTE b)
776800 then Just $ unsafeCoerce Refl -- This unsafeCoerce is safe because the same SpiderTimelineEnv can't have two different 'x' arguments
777801 else Nothing
778802
@@ -782,9 +806,9 @@ data EventEnv x
782806 , eventEnvDynInits :: !(IORef [SomeDynInit x])
783807 , eventEnvMergeUpdates :: !(IORef [SomeMergeUpdate x])
784808 , eventEnvMergeInits :: !(IORef [SomeMergeInit x]) -- Needed for Subscribe
785− , eventEnvClears :: !(IORef [SomeClear]) -- Needed for Subscribe
786− , eventEnvIntClears :: !(IORef [SomeIntClear])
787− , eventEnvRootClears :: !(IORef [SomeRootClear])
809+ , eventEnvClears :: !(IORef [Some Clear]) -- Needed for Subscribe
810+ , eventEnvIntClears :: !(IORef [Some IntClear])
811+ , eventEnvRootClears :: !(IORef [Some RootClear])
788812 , eventEnvCurrentHeight :: !(IORef Height) -- Needed for Subscribe
789813 , eventEnvResetCoincidences :: !(IORef [SomeResetCoincidence x]) -- Needed for Subscribe
790814 , eventEnvDelayedMerges :: !(IORef (IntMap [EventM x ()]))
@@ -795,7 +819,7 @@ runEventM :: EventM x a -> IO a
795819runEventM = unEventM
796820
797821asksEventEnv :: forall x a. HasSpiderTimeline x => (EventEnv x -> a) -> EventM x a
798−asksEventEnv f = return $ f $ _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
822+asksEventEnv f = return $ f $ _spiderTimeline_eventEnv (unSTE (spiderTimeline :: SpiderTimelineEnv x))
799823
800824class MonadIO m => Defer a m where
801825 getDeferralQueue :: m (IORef [a])
@@ -856,29 +880,29 @@ putCurrentHeight h = do
856880 heightRef <- asksEventEnv eventEnvCurrentHeight
857881 liftIO $ writeIORef heightRef $! h
858882
859−instance HasSpiderTimeline x => Defer SomeClear (EventM x) where
883+instance HasSpiderTimeline x => Defer (Some Clear) (EventM x) where
860884 {-# INLINE getDeferralQueue #-}
861885 getDeferralQueue = asksEventEnv eventEnvClears
862886
863887{-# INLINE scheduleClear #-}
864−scheduleClear :: Defer SomeClear m => IORef (Maybe a) -> m ()
865−scheduleClear r = defer $ SomeClear r
888+scheduleClear :: Defer (Some Clear) m => IORef (Maybe a) -> m ()
889+scheduleClear r = defer $ Some $ Clear r
866890
867−instance HasSpiderTimeline x => Defer SomeIntClear (EventM x) where
891+instance HasSpiderTimeline x => Defer (Some IntClear) (EventM x) where
868892 {-# INLINE getDeferralQueue #-}
869893 getDeferralQueue = asksEventEnv eventEnvIntClears
870894
871895{-# INLINE scheduleIntClear #-}
872−scheduleIntClear :: Defer SomeIntClear m => IORef (IntMap a) -> m ()
873−scheduleIntClear r = defer $ SomeIntClear r
896+scheduleIntClear :: Defer (Some IntClear) m => IORef (IntMap a) -> m ()
897+scheduleIntClear r = defer $ Some $ IntClear r
874898
875−instance HasSpiderTimeline x => Defer SomeRootClear (EventM x) where
899+instance HasSpiderTimeline x => Defer (Some RootClear) (EventM x) where
876900 {-# INLINE getDeferralQueue #-}
877901 getDeferralQueue = asksEventEnv eventEnvRootClears
878902
879903{-# INLINE scheduleRootClear #-}
880−scheduleRootClear :: Defer SomeRootClear m => IORef (DMap k Identity) -> m ()
881−scheduleRootClear r = defer $ SomeRootClear r
904+scheduleRootClear :: Defer (Some RootClear) m => IORef (DMap k Identity) -> m ()
905+scheduleRootClear r = defer $ Some $ RootClear r
882906
883907instance HasSpiderTimeline x => Defer (SomeResetCoincidence x) (EventM x) where
884908 {-# INLINE getDeferralQueue #-}
@@ -933,9 +957,9 @@ getHoldEventSubscription h = do
933957
934958type BehaviorEnv x = (Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]), IORef [SomeHoldInit x])
935959
936−--type role BehaviorM representational
937960-- BehaviorM can sample behaviors
938−newtype BehaviorM x a = BehaviorM { unBehaviorM :: ReaderT (BehaviorEnv x) IO a } deriving (Functor, Applicative, MonadIO, MonadFix)
961+newtype BehaviorM x a = BehaviorM { unBehaviorM :: ReaderIO (BehaviorEnv x) a }
962+ deriving (Functor, Applicative, MonadIO, MonadFix, MonadReader (BehaviorEnv x))
939963
940964instance Monad (BehaviorM x) where
941965 {-# INLINE (>>=) #-}
@@ -951,7 +975,7 @@ data BehaviorSubscribed x a
951975 = forall p. BehaviorSubscribedHold (Hold x p)
952976 | BehaviorSubscribedPull (PullSubscribed x a)
953977
954−data SomeBehaviorSubscribed x = forall a. SomeBehaviorSubscribed (BehaviorSubscribed x a)
978+newtype SomeBehaviorSubscribed x = SomeBehaviorSubscribed (Some (BehaviorSubscribed x))
955979
956980--type role PullSubscribed representational
957981data PullSubscribed x a
@@ -986,7 +1010,7 @@ data RootSubscribed x a = forall k. GCompare k => RootSubscribed
9861010#endif
9871011 }
9881012
989−data Root x (k :: * -> *)
1013+data Root x k
9901014 = Root { rootOccurrence :: !(IORef (DMap k Identity)) -- The currently-firing occurrence of this event
9911015 , rootSubscribed :: !(IORef (DMap k (RootSubscribed x)))
9921016 , rootInit :: !(forall a. k a -> RootTrigger x a -> IO (IO ()))
@@ -1056,25 +1080,25 @@ heightBagVerify b@(HeightBag s c) = if
10561080heightBagVerify = id
10571081#endif
10581082
1059−data FanSubscribedChildren (x :: *) k a = FanSubscribedChildren
1060− { _fanSubscribedChildren_list :: !(WeakBag (Subscriber x a))
1061− , _fanSubscribedChildren_self :: {-# NOUNPACK #-} !(k a, FanSubscribed x k)
1062− , _fanSubscribedChildren_weakSelf :: !(IORef (Weak (k a, FanSubscribed x k)))
1083+data FanSubscribedChildren x k v a = FanSubscribedChildren
1084+ { _fanSubscribedChildren_list :: !(WeakBag (Subscriber x (v a)))
1085+ , _fanSubscribedChildren_self :: {-# NOUNPACK #-} !(k a, FanSubscribed x k v)
1086+ , _fanSubscribedChildren_weakSelf :: !(IORef (Weak (k a, FanSubscribed x k v)))
10631087 }
10641088
1065−data FanSubscribed (x :: *) k
1066− = FanSubscribed { fanSubscribedCachedSubscribed :: !(IORef (Maybe (FanSubscribed x k)))
1067− , fanSubscribedOccurrence :: !(IORef (Maybe (DMap k Identity)))
1068− , fanSubscribedSubscribers :: !(IORef (DMap k (FanSubscribedChildren x k))) -- This DMap should never be empty
1089+data FanSubscribed x k v
1090+ = FanSubscribed { fanSubscribedCachedSubscribed :: !(IORef (Maybe (FanSubscribed x k v)))
1091+ , fanSubscribedOccurrence :: !(IORef (Maybe (DMap k v)))
1092+ , fanSubscribedSubscribers :: !(IORef (DMap k (FanSubscribedChildren x k v))) -- This DMap should never be empty
10691093 , fanSubscribedParent :: !(EventSubscription x)
10701094#ifdef DEBUG_NODEIDS
10711095 , fanSubscribedNodeId :: Int
10721096#endif
10731097 }
10741098
1075−data Fan x k
1076− = Fan { fanParent :: !(Event x (DMap k Identity))
1077− , fanSubscribed :: !(IORef (Maybe (FanSubscribed x k)))
1099+data Fan x k v
1100+ = Fan { fanParent :: !(Event x (DMap k v))
1101+ , fanSubscribed :: !(IORef (Maybe (FanSubscribed x k v)))
10781102 }
10791103
10801104data SwitchSubscribed x a
@@ -1128,24 +1152,32 @@ newInvalidatorSwitch subd = return $! InvalidatorSwitch subd
11281152newInvalidatorPull :: Pull x a -> IO (Invalidator x)
11291153newInvalidatorPull p = return $! InvalidatorPull p
11301154
1131−instance HasSpiderTimeline x => FunctorMaybe (Event x) where
1132− fmapMaybe f = push $ return . f
1155+instance HasSpiderTimeline x => Filterable (Event x) where
1156+ mapMaybe f = push $ return . f
11331157
11341158instance HasSpiderTimeline x => Align (Event x) where
11351159 nil = eventNever
1136− align ea eb = fmapMaybe dmapToThese $ merge $ dynamicConst $ DMap.fromDistinctAscList [LeftTag :=> ea, RightTag :=> eb]
1160+#if MIN_VERSION_these(0, 8, 0)
1161+instance HasSpiderTimeline x => Semialign (Event x) where
1162+#endif
1163+ align ea eb = mapMaybe dmapToThese $ mergeG coerce $ dynamicConst $
1164+ DMap.fromDistinctAscList [LeftTag :=> ea, RightTag :=> eb]
1165+
1166+#if defined(MIN_VERSION_semialign)
1167+ zip x y = mapMaybe justThese $ align x y
1168+#endif
11371169
11381170data DynType x p = UnsafeDyn !(BehaviorM x (PatchTarget p), Event x p)
11391171 | BuildDyn !(EventM x (PatchTarget p), Event x p)
11401172 | HoldDyn !(Hold x p)
11411173
1142−newtype Dyn x p = Dyn { unDyn :: IORef (DynType x p) }
1174+newtype Dyn (x :: Type) p = Dyn { unDyn :: IORef (DynType x p) }
11431175
1144−newMapDyn :: HasSpiderTimeline x => (a -> b) -> Dynamic x (Identity a) -> Dynamic x (Identity b)
1176+newMapDyn :: HasSpiderTimeline x => (a -> b) -> DynamicS x (Identity a) -> DynamicS x (Identity b)
11451177newMapDyn f d = dynamicDynIdentity $ unsafeBuildDynamic (fmap f $ readBehaviorTracked $ dynamicCurrent d) (Identity . f . runIdentity <$> dynamicUpdated d)
11461178
11471179--TODO: Avoid the duplication between this and R.zipDynWith
1148−zipDynWith :: HasSpiderTimeline x => (a -> b -> c) -> Dynamic x (Identity a) -> Dynamic x (Identity b) -> Dynamic x (Identity c)
1180+zipDynWith :: HasSpiderTimeline x => (a -> b -> c) -> DynamicS x (Identity a) -> DynamicS x (Identity b) -> DynamicS x (Identity c)
11491181zipDynWith f da db =
11501182 let eab = align (dynamicUpdated da) (dynamicUpdated db)
11511183 ec = flip push eab $ \o -> do
@@ -1168,18 +1200,12 @@ buildDynamic readV0 v' = do
11681200 return d
11691201
11701202unsafeBuildDynamic :: BehaviorM x (PatchTarget p) -> Event x p -> Dyn x p
1171−unsafeBuildDynamic readV0 v' = Dyn $ unsafeNewIORef x $ UnsafeDyn x
1172− where x = (readV0, v')
1203+unsafeBuildDynamic readV0 v' =
1204+ Dyn $ unsafePerformIO $ newIORef $ UnsafeDyn (readV0, v')
11731205
11741206-- ResultM can read behaviors and events
11751207type ResultM = EventM
11761208
1177−{-# NOINLINE unsafeNewIORef #-}
1178−unsafeNewIORef :: a -> b -> IORef b
1179−unsafeNewIORef a b = unsafePerformIO $ do
1180− touch a
1181− newIORef b
1182−
11831209instance HasSpiderTimeline x => Functor (Event x) where
11841210 fmap f = push $ return . Just . f
11851211
@@ -1192,33 +1218,42 @@ push f e = cacheEvent (pushCheap f e)
11921218
11931219{-# INLINABLE pull #-}
11941220pull :: BehaviorM x a -> Behavior x a
1195−pull a = behaviorPull $ Pull
1196− { pullCompute = a
1197− , pullValue = unsafeNewIORef a Nothing
1221+pull a = unsafePerformIO $ do
1222+ ref <- newIORef Nothing
11981223#ifdef DEBUG_NODEIDS
1199− , pullNodeId = unsafeNodeId a
1224+ nid <- newNodeId
12001225#endif
1201− }
1226+ pure $ behaviorPull $ Pull
1227+ { pullCompute = a
1228+ , pullValue = ref
1229+#ifdef DEBUG_NODEIDS
1230+ , pullNodeId = nid
1231+#endif
1232+ }
12021233
12031234{-# INLINABLE switch #-}
12041235switch :: HasSpiderTimeline x => Behavior x (Event x a) -> Event x a
1205−switch a = eventSwitch $ Switch
1206− { switchParent = a
1207− , switchSubscribed = unsafeNewIORef a Nothing
1208− }
1236+switch a = unsafePerformIO $ do
1237+ ref <- newIORef Nothing
1238+ pure $ eventSwitch $ Switch
1239+ { switchParent = a
1240+ , switchSubscribed = ref
1241+ }
12091242
12101243coincidence :: HasSpiderTimeline x => Event x (Event x a) -> Event x a
1211−coincidence a = eventCoincidence $ Coincidence
1212− { coincidenceParent = a
1213− , coincidenceSubscribed = unsafeNewIORef a Nothing
1214− }
1244+coincidence a = unsafePerformIO $ do
1245+ ref <- newIORef Nothing
1246+ pure $ eventCoincidence $ Coincidence
1247+ { coincidenceParent = a
1248+ , coincidenceSubscribed = ref
1249+ }
12151250
12161251-- Propagate the given event occurrence; before cleaning up, run the given action, which may read the state of events and behaviors
12171252run :: forall x b. HasSpiderTimeline x => [DSum (RootTrigger x) Identity] -> ResultM x b -> SpiderHost x b
12181253run roots after = do
12191254 tracePropagate (Proxy :: Proxy x) $ "Running an event frame with " <> show (length roots) <> " events"
12201255 let t = spiderTimeline :: SpiderTimelineEnv x
1221− result <- SpiderHost $ withMVar (_spiderTimeline_lock t) $ \_ -> unSpiderHost $ runFrame $ do
1256+ result <- SpiderHost $ withMVar (_spiderTimeline_lock (unSTE t)) $ \_ -> unSpiderHost $ runFrame $ do
12221257 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
12231258 occBefore <- liftIO $ do
12241259 occBefore <- readIORef occRef
@@ -1256,11 +1291,11 @@ scheduleMerge' initialHeight heightRef a = scheduleMerge initialHeight $ do
12561291 GT -> scheduleMerge' height heightRef a -- The height has been increased (by a coincidence event; TODO: is this the only way?)
12571292 EQ -> a
12581293
1259−data SomeClear = forall a. SomeClear {-# UNPACK #-} !(IORef (Maybe a))
1294+newtype Clear a = Clear (IORef (Maybe a))
12601295
1261−data SomeIntClear = forall a. SomeIntClear {-# UNPACK #-} !(IORef (IntMap a))
1296+newtype IntClear a = IntClear (IORef (IntMap a))
12621297
1263−data SomeRootClear = forall k. SomeRootClear {-# UNPACK #-} !(IORef (DMap k Identity))
1298+newtype RootClear k = RootClear (IORef (DMap k Identity))
12641299
12651300data SomeAssignment x = forall a. SomeAssignment {-# UNPACK #-} !(IORef a) {-# UNPACK #-} !(IORef [Weak (Invalidator x)]) a
12661301
@@ -1282,9 +1317,9 @@ type WeakList a = [Weak a]
12821317withIncreasedDepth :: CanTrace x m => m a -> m a
12831318withIncreasedDepth a = do
12841319 spiderTimeline <- askSpiderTimelineEnv
1285− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) succ
1320+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) succ
12861321 result <- a
1287− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) pred
1322+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) pred
12881323 return result
12891324#else
12901325withIncreasedDepth :: m a -> m a
@@ -1311,7 +1346,7 @@ traceMWhen _ b getMessage = when b $ do
13111346 message <- getMessage
13121347#ifdef DEBUG
13131348 spiderTimeline <- askSpiderTimelineEnv
1314− d <- liftIO $ readIORef $ _spiderTimeline_depth spiderTimeline
1349+ d <- liftIO $ readIORef $ _spiderTimeline_depth $ unSTE spiderTimeline
13151350#else
13161351 let d = 0
13171352#endif
@@ -1352,25 +1387,25 @@ propagateSubscriberHold h a = do
13521387data SomeResetCoincidence x = forall a. SomeResetCoincidence !(EventSubscription x) !(Maybe (CoincidenceSubscribed x a)) -- The CoincidenceSubscriber will be present only if heights need to be reset
13531388
13541389runBehaviorM :: BehaviorM x a -> Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]) -> IORef [SomeHoldInit x] -> IO a
1355−runBehaviorM a mwi holdInits = runReaderT (unBehaviorM a) (mwi, holdInits)
1390+runBehaviorM a mwi holdInits = runReaderIO (unBehaviorM a) (mwi, holdInits)
13561391
13571392askInvalidator :: BehaviorM x (Maybe (Weak (Invalidator x)))
13581393askInvalidator = do
1359− (!m, _) <- BehaviorM ask
1394+ (!m, _) <- ask
13601395 case m of
13611396 Nothing -> return Nothing
13621397 Just (!wi, _) -> return $ Just wi
13631398
13641399askParentsRef :: BehaviorM x (Maybe (IORef [SomeBehaviorSubscribed x]))
13651400askParentsRef = do
1366− (!m, _) <- BehaviorM ask
1401+ (!m, _) <- ask
13671402 case m of
13681403 Nothing -> return Nothing
13691404 Just (_, !p) -> return $ Just p
13701405
13711406askBehaviorHoldInits :: BehaviorM x (IORef [SomeHoldInit x])
13721407askBehaviorHoldInits = do
1373− (_, !his) <- BehaviorM ask
1408+ (_, !his) <- ask
13741409 return his
13751410
13761411{-# INLINE getDynHold #-}
@@ -1415,6 +1450,9 @@ getRootSubscribed k r sub = do
14151450 when debugPropagate $ putStrLn $ "getRootSubscribed: calling rootInit"
14161451 uninit <- rootInit r k $ RootTrigger (subs, rootOccurrence r, k)
14171452 writeIORef uninitRef $! uninit
1453+#ifdef DEBUG_NODEIDS
1454+ nid <- newNodeId
1455+#endif
14181456 let !subscribed = RootSubscribed
14191457 { rootSubscribedKey = k
14201458 , rootSubscribedCachedSubscribed = cached
@@ -1423,7 +1461,7 @@ getRootSubscribed k r sub = do
14231461 , rootSubscribedUninit = uninit
14241462 , rootSubscribedWeakSelf = weakSelf
14251463#ifdef DEBUG_NODEIDS
1426− , rootSubscribedNodeId = unsafeNodeId (k, r, subs)
1464+ , rootSubscribedNodeId = nid
14271465#endif
14281466 }
14291467 -- If we die at the same moment that all our children die, they will
@@ -1472,16 +1510,10 @@ newFanInt = do
14721510 , _fanInt_occRef = occRef
14731511 }
14741512
1475−{-# NOINLINE unsafeNewFanInt #-}
1476−unsafeNewFanInt :: b -> FanInt x a
1477−unsafeNewFanInt b = unsafePerformIO $ do
1478− touch b
1479− newFanInt
1480−
14811513fanInt :: HasSpiderTimeline x => Event x (IntMap a) -> EventSelectorInt x a
1482−fanInt p =
1483− let self = unsafeNewFanInt p
1484− in EventSelectorInt $ \k -> Event $ \sub -> do
1514+fanInt p = unsafePerformIO $ do
1515+ self <- newFanInt
1516+ pure $ EventSelectorInt $ \k -> Event $ \sub -> do
14851517 isEmpty <- liftIO $ FastMutableIntMap.isEmpty (_fanInt_subscribers self)
14861518 when isEmpty $ do -- This is the first subscriber, so we need to subscribe to our input
14871519 (subscription, parentOcc) <- subscribeAndRead p $ Subscriber
@@ -1517,7 +1549,7 @@ fanInt p =
15171549 return (EventSubscription (FastWeakBag.remove t) $! EventSubscribed heightRef $! toAny (_fanInt_subscriptionRef self, t), IntMap.lookup k currentOcc)
15181550
15191551{-# INLINABLE getFanSubscribed #-}
1520−getFanSubscribed :: (HasSpiderTimeline x, GCompare k) => k a -> Fan x k -> Subscriber x a -> EventM x (WeakBagTicket, FanSubscribed x k, Maybe a)
1552+getFanSubscribed :: (HasSpiderTimeline x, GCompare k) => k a -> Fan x k v -> Subscriber x (v a) -> EventM x (WeakBagTicket, FanSubscribed x k v, Maybe (v a))
15211553getFanSubscribed k f sub = do
15221554 mSubscribed <- liftIO $ readIORef $ fanSubscribed f
15231555 case mSubscribed of
@@ -1535,13 +1567,16 @@ getFanSubscribed k f sub = do
15351567 subscribersRef <- liftIO $ newIORef $ error "getFanSubscribed: subscribersRef not yet initialized"
15361568 occRef <- liftIO $ newIORef parentOcc
15371569 when (isJust parentOcc) $ scheduleClear occRef
1570+#ifdef DEBUG_NODEIDS
1571+ nid <- liftIO newNodeId
1572+#endif
15381573 let subscribed = FanSubscribed
15391574 { fanSubscribedCachedSubscribed = fanSubscribed f
15401575 , fanSubscribedOccurrence = occRef
15411576 , fanSubscribedParent = subscription
15421577 , fanSubscribedSubscribers = subscribersRef
15431578#ifdef DEBUG_NODEIDS
1544− , fanSubscribedNodeId = unsafeNodeId f
1579+ , fanSubscribedNodeId = nid
15451580#endif
15461581 }
15471582 let !self = (k, subscribed)
@@ -1551,7 +1586,7 @@ getFanSubscribed k f sub = do
15511586 liftIO $ writeIORef (fanSubscribed f) $ Just subscribed
15521587 return (slnForSub, subscribed, coerce $ DMap.lookup k =<< parentOcc)
15531588
1554−cleanupFanSubscribed :: GCompare k => (k a, FanSubscribed x k) -> IO ()
1589+cleanupFanSubscribed :: GCompare k => (k a, FanSubscribed x k v) -> IO ()
15551590cleanupFanSubscribed (k, subscribed) = do
15561591 subscribers <- readIORef $ fanSubscribedSubscribers subscribed
15571592 let reducedSubscribers = DMap.delete k subscribers
@@ -1563,7 +1598,7 @@ cleanupFanSubscribed (k, subscribed) = do
15631598 else writeIORef (fanSubscribedSubscribers subscribed) $! reducedSubscribers
15641599
15651600{-# INLINE subscribeFanSubscribed #-}
1566−subscribeFanSubscribed :: GCompare k => k a -> FanSubscribed x k -> Subscriber x a -> IO WeakBagTicket
1601+subscribeFanSubscribed :: GCompare k => k a -> FanSubscribed x k v -> Subscriber x (v a) -> IO WeakBagTicket
15671602subscribeFanSubscribed k subscribed sub = do
15681603 subscribers <- readIORef $ fanSubscribedSubscribers subscribed
15691604 case DMap.lookup k subscribers of
@@ -1601,6 +1636,9 @@ getSwitchSubscribed s sub = do
16011636 when (isJust parentOcc) $ scheduleClear occRef
16021637 weakSelf <- liftIO $ newIORef $ error "getSwitchSubscribed: weakSelf not yet initialized"
16031638 (subs, slnForSub) <- liftIO $ WeakBag.singleton sub weakSelf cleanupSwitchSubscribed
1639+#ifdef DEBUG_NODEIDS
1640+ nid <- liftIO newNodeId
1641+#endif
16041642 let !subscribed = SwitchSubscribed
16051643 { switchSubscribedCachedSubscribed = switchSubscribed s
16061644 , switchSubscribedOccurrence = occRef
@@ -1613,7 +1651,7 @@ getSwitchSubscribed s sub = do
16131651 , switchSubscribedCurrentParent = subscriptionRef
16141652 , switchSubscribedWeakSelf = weakSelf
16151653#ifdef DEBUG_NODEIDS
1616− , switchSubscribedNodeId = unsafeNodeId s
1654+ , switchSubscribedNodeId = nid
16171655#endif
16181656 }
16191657 liftIO $ writeIORef weakSelf =<< evaluate =<< mkWeakPtrWithDebug subscribed "switchSubscribedWeakSelf"
@@ -1658,6 +1696,9 @@ getCoincidenceSubscribed c sub = do
16581696 scheduleClear innerSubdRef
16591697 weakSelf <- liftIO $ newIORef $ error "getCoincidenceSubscribed: weakSelf not yet implemented"
16601698 (subs, slnForSub) <- liftIO $ WeakBag.singleton sub weakSelf cleanupCoincidenceSubscribed
1699+#ifdef DEBUG_NODEIDS
1700+ nid <- liftIO newNodeId
1701+#endif
16611702 let subscribed = CoincidenceSubscribed
16621703 { coincidenceSubscribedCachedSubscribed = coincidenceSubscribed c
16631704 , coincidenceSubscribedOccurrence = occRef
@@ -1668,7 +1709,7 @@ getCoincidenceSubscribed c sub = do
16681709 , coincidenceSubscribedInnerParent = innerSubdRef
16691710 , coincidenceSubscribedWeakSelf = weakSelf
16701711#ifdef DEBUG_NODEIDS
1671− , coincidenceSubscribedNodeId = unsafeNodeId c
1712+ , coincidenceSubscribedNodeId = nid
16721713#endif
16731714 }
16741715 liftIO $ writeIORef weakSelf =<< evaluate =<< mkWeakPtrWithDebug subscribed "CoincidenceSubscribed"
@@ -1685,26 +1726,34 @@ cleanupCoincidenceSubscribed subscribed = do
16851726subscribeCoincidenceSubscribed :: CoincidenceSubscribed x a -> Subscriber x a -> IO WeakBagTicket
16861727subscribeCoincidenceSubscribed subscribed sub = WeakBag.insert sub (coincidenceSubscribedSubscribers subscribed) (coincidenceSubscribedWeakSelf subscribed) cleanupCoincidenceSubscribed
16871728
1688−{-# INLINE merge #-}
1689−merge :: forall k x. (HasSpiderTimeline x, GCompare k) => Dynamic x (PatchDMap k (Event x)) -> Event x (DMap k Identity)
1690−merge d = cacheEvent (mergeCheap d)
1729+{-# INLINE mergeG #-}
1730+mergeG :: forall k q x v. (HasSpiderTimeline x, GCompare k)
1731+ => (forall a. q a -> Event x (v a))
1732+ -> DynamicS x (PatchDMap k q) -> Event x (DMap k v)
1733+mergeG nt d = cacheEvent (mergeCheap nt d)
16911734
16921735{-# INLINE mergeWithMove #-}
1693−mergeWithMove :: forall k x. (HasSpiderTimeline x, GCompare k) => Dynamic x (PatchDMapWithMove k (Event x)) -> Event x (DMap k Identity)
1694−mergeWithMove d = cacheEvent (mergeCheapWithMove d)
1736+mergeWithMove :: forall k v q x. (HasSpiderTimeline x, GCompare k)
1737+ => (forall a. q a -> Event x (v a))
1738+ -> DynamicS x (PatchDMapWithMove k q) -> Event x (DMap k v)
1739+mergeWithMove nt d = cacheEvent (mergeCheapWithMove nt d)
16951740
16961741{-# INLINE [1] mergeCheap #-}
1697−mergeCheap :: forall k x. (HasSpiderTimeline x, GCompare k) => Dynamic x (PatchDMap k (Event x)) -> Event x (DMap k Identity)
1698−mergeCheap = mergeCheap' getInitialSubscribers updateMe destroy
1742+mergeCheap
1743+ :: forall k x q v. (HasSpiderTimeline x, GCompare k)
1744+ => (forall a. q a -> Event x (v a))
1745+ -> DynamicS x (PatchDMap k q)
1746+ -> Event x (DMap k v)
1747+mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
16991748 where
1700− updateMe :: MergeUpdateFunc k x (PatchDMap k (Event x)) (MergeSubscribedParent x)
1749+ updateMe :: MergeUpdateFunc k v x (PatchDMap k q) (MergeSubscribedParent x)
17011750 updateMe subscriber heightBagRef oldParents (PatchDMap p) = do
17021751 let f (subscriptionsToKill, ps) (k :=> ComposeMaybe me) = do
17031752 (mOldSubd, newPs) <- case me of
17041753 Nothing -> return $ DMap.updateLookupWithKey (\_ _ -> Nothing) k ps
17051754 Just e -> do
17061755 let s = subscriber $ return k
1707− subscription@(EventSubscription _ subd) <- subscribe e s
1756+ subscription@(EventSubscription _ subd) <- subscribe (nt e) s
17081757 newParentHeight <- liftIO $ getEventSubscribedHeight subd
17091758 let newParent = MergeSubscribedParent subscription
17101759 liftIO $ modifyIORef' heightBagRef $ heightBagAdd newParentHeight
@@ -1714,28 +1763,33 @@ mergeCheap = mergeCheap' getInitialSubscribers updateMe destroy
17141763 liftIO $ modifyIORef heightBagRef $ heightBagRemove oldHeight
17151764 return (maybeToList (unMergeSubscribedParent <$> mOldSubd) ++ subscriptionsToKill, newPs)
17161765 foldM f ([], oldParents) $ DMap.toList p
1717− getInitialSubscribers :: MergeInitFunc k x (MergeSubscribedParent x)
1766+
1767+ getInitialSubscribers :: MergeInitFunc k v q x (MergeSubscribedParent x)
17181768 getInitialSubscribers initialParents subscriber = do
17191769 subscribers <- forM (DMap.toList initialParents) $ \(k :=> e) -> do
17201770 let s = subscriber $ return k
1721− (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead e s
1771+ (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead (nt e) s
17221772 height <- liftIO $ getEventSubscribedHeight parentSubd
1723− return (fmap (\x -> k :=> Identity x) parentOcc, height, k :=> MergeSubscribedParent subscription)
1773+ return (fmap (k :=>) parentOcc, height, k :=> MergeSubscribedParent subscription)
17241774 return ( DMap.fromDistinctAscList $ mapMaybe (\(x, _, _) -> x) subscribers
17251775 , fmap (\(_, h, _) -> h) subscribers --TODO: Assert that there's no invalidHeight in here
17261776 , DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
17271777 )
1778+
17281779 destroy :: MergeDestroyFunc k (MergeSubscribedParent x)
17291780 destroy s = forM_ (DMap.toList s) $ \(_ :=> MergeSubscribedParent sub) -> unsubscribe sub
17301781
17311782{-# INLINE [1] mergeCheapWithMove #-}
1732−mergeCheapWithMove :: forall k x. (HasSpiderTimeline x, GCompare k) => Dynamic x (PatchDMapWithMove k (Event x)) -> Event x (DMap k Identity)
1733−mergeCheapWithMove = mergeCheap' getInitialSubscribers updateMe destroy
1783+mergeCheapWithMove :: forall k x v q. (HasSpiderTimeline x, GCompare k)
1784+ => (forall a. q a -> Event x (v a))
1785+ -> DynamicS x (PatchDMapWithMove k q)
1786+ -> Event x (DMap k v)
1787+mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
17341788 where
1735− updateMe :: MergeUpdateFunc k x (PatchDMapWithMove k (Event x)) (MergeSubscribedParentWithMove x k)
1789+ updateMe :: MergeUpdateFunc k v x (PatchDMapWithMove k q) (MergeSubscribedParentWithMove x k)
17361790 updateMe subscriber heightBagRef oldParents p = do
17371791 -- Prepare new parents for insertion
1738− let subscribeParent :: forall a. k a -> Event x a -> EventM x (MergeSubscribedParentWithMove x k a)
1792+ let subscribeParent :: forall a. k a -> Event x (v a) -> EventM x (MergeSubscribedParentWithMove x k a)
17391793 subscribeParent k e = do
17401794 keyRef <- liftIO $ newIORef k
17411795 let s = subscriber $ liftIO $ readIORef keyRef
@@ -1744,9 +1798,9 @@ mergeCheapWithMove = mergeCheap' getInitialSubscribers updateMe destroy
17441798 newParentHeight <- getEventSubscribedHeight subd
17451799 modifyIORef' heightBagRef $ heightBagAdd newParentHeight
17461800 return $ MergeSubscribedParentWithMove subscription keyRef
1747− p' <- PatchDMapWithMove.traversePatchDMapWithMoveWithKey subscribeParent p
1801+ p' <- PatchDMapWithMove.traversePatchDMapWithMoveWithKey (\k q -> subscribeParent k (nt q)) p
17481802 -- Collect old parents for deletion and update the keys of moved parents
1749− let moveOrDelete :: forall a. k a -> PatchDMapWithMove.NodeInfo k (Event x) a -> MergeSubscribedParentWithMove x k a -> Constant (EventM x (Maybe (EventSubscription x))) a
1803+ let moveOrDelete :: forall a. k a -> PatchDMapWithMove.NodeInfo k q a -> MergeSubscribedParentWithMove x k a -> Constant (EventM x (Maybe (EventSubscription x))) a
17501804 moveOrDelete _ ni parent = Constant $ case getComposeMaybe $ PatchDMapWithMove._nodeInfo_to ni of
17511805 Nothing -> do
17521806 oldHeight <- liftIO $ getEventSubscribedHeight $ _eventSubscription_subscribed $ _mergeSubscribedParentWithMove_subscription parent
@@ -1757,46 +1811,47 @@ mergeCheapWithMove = mergeCheap' getInitialSubscribers updateMe destroy
17571811 return Nothing
17581812 toDelete <- fmap catMaybes $ mapM (\(_ :=> v) -> getConstant v) $ DMap.toList $ DMap.intersectionWithKey moveOrDelete (unPatchDMapWithMove p) oldParents
17591813 return (toDelete, applyAlways p' oldParents)
1760− getInitialSubscribers :: MergeInitFunc k x (MergeSubscribedParentWithMove x k)
1814+ getInitialSubscribers :: MergeInitFunc k v q x (MergeSubscribedParentWithMove x k)
17611815 getInitialSubscribers initialParents subscriber = do
17621816 subscribers <- forM (DMap.toList initialParents) $ \(k :=> e) -> do
17631817 keyRef <- liftIO $ newIORef k
17641818 let s = subscriber $ liftIO $ readIORef keyRef
1765− (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead e s
1819+ (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead (nt e) s
17661820 height <- liftIO $ getEventSubscribedHeight parentSubd
1767− return (fmap (\x -> k :=> Identity x) parentOcc, height, k :=> MergeSubscribedParentWithMove subscription keyRef)
1821+ return (fmap (k :=>) parentOcc, height, k :=> MergeSubscribedParentWithMove subscription keyRef)
17681822 return ( DMap.fromDistinctAscList $ mapMaybe (\(x, _, _) -> x) subscribers
17691823 , fmap (\(_, h, _) -> h) subscribers --TODO: Assert that there's no invalidHeight in here
17701824 , DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
17711825 )
1826+
17721827 destroy :: MergeDestroyFunc k (MergeSubscribedParentWithMove x k)
17731828 destroy s = forM_ (DMap.toList s) $ \(_ :=> MergeSubscribedParentWithMove sub _) -> unsubscribe sub
17741829
1775−type MergeUpdateFunc k x p s
1776− = (forall a. EventM x (k a) -> Subscriber x a)
1830+type MergeUpdateFunc k v x p s
1831+ = (forall a. EventM x (k a) -> Subscriber x (v a))
17771832 -> IORef HeightBag
17781833 -> DMap k s
17791834 -> p
17801835 -> EventM x ([EventSubscription x], DMap k s)
17811836
1782−type MergeInitFunc k x s
1783− = DMap k (Event x)
1784− -> (forall a. EventM x (k a) -> Subscriber x a)
1785− -> EventM x (DMap k Identity, [Height], DMap k s)
1837+type MergeInitFunc k v q x s
1838+ = DMap k q
1839+ -> (forall a. EventM x (k a) -> Subscriber x (v a))
1840+ -> EventM x (DMap k v, [Height], DMap k s)
17861841
17871842type MergeDestroyFunc k s
17881843 = DMap k s
17891844 -> IO ()
17901845
1791−data Merge x k s = Merge
1846+data Merge x k v s = Merge
17921847 { _merge_parentsRef :: {-# UNPACK #-} !(IORef (DMap k s))
17931848 , _merge_heightBagRef :: {-# UNPACK #-} !(IORef HeightBag)
17941849 , _merge_heightRef :: {-# UNPACK #-} !(IORef Height)
1795− , _merge_sub :: {-# UNPACK #-} !(Subscriber x (DMap k Identity))
1796− , _merge_accumRef :: {-# UNPACK #-} !(IORef (DMap k Identity))
1850+ , _merge_sub :: {-# UNPACK #-} !(Subscriber x (DMap k v))
1851+ , _merge_accumRef :: {-# UNPACK #-} !(IORef (DMap k v))
17971852 }
17981853
1799−invalidateMergeHeight :: Merge x k s -> IO ()
1854+invalidateMergeHeight :: Merge x k v s -> IO ()
18001855invalidateMergeHeight m = invalidateMergeHeight' (_merge_heightRef m) (_merge_sub m)
18011856
18021857invalidateMergeHeight' :: IORef Height -> Subscriber x a -> IO ()
@@ -1806,8 +1861,7 @@ invalidateMergeHeight' heightRef sub = do
18061861 writeIORef heightRef $! invalidHeight
18071862 subscriberInvalidateHeight sub oldHeight
18081863
1809−
1810−revalidateMergeHeight :: Merge x k s -> IO ()
1864+revalidateMergeHeight :: Merge x k v s -> IO ()
18111865revalidateMergeHeight m = do
18121866 currentHeight <- readIORef $ _merge_heightRef m
18131867 when (currentHeight == invalidHeight) $ do -- revalidateMergeHeight may be called multiple times; perhaps the's a way to finesse it to avoid this check
@@ -1823,19 +1877,19 @@ revalidateMergeHeight m = do
18231877 subscriberRecalculateHeight (_merge_sub m) height
18241878 GT -> error $ "revalidateMergeHeight: more heights (" <> show (heightBagSize heights) <> ") than parents (" <> show (DMap.size parents) <> ") for Merge"
18251879
1826−scheduleMergeSelf :: HasSpiderTimeline x => Merge x k s -> Height -> EventM x ()
1880+scheduleMergeSelf :: HasSpiderTimeline x => Merge x k v s -> Height -> EventM x ()
18271881scheduleMergeSelf m height = scheduleMerge' height (_merge_heightRef m) $ do
18281882 vals <- liftIO $ readIORef $ _merge_accumRef m
18291883 liftIO $ writeIORef (_merge_accumRef m) $! DMap.empty -- Once we're done with this, we can clear it immediately, because if there's a cacheEvent in front of us, it'll handle subsequent subscribers, and if not, we won't get subsequent subscribers
18301884 --TODO: Assert that m is not empty
18311885 subscriberPropagate (_merge_sub m) vals
18321886
1833−mergeSubscriber :: forall x k s a. (HasSpiderTimeline x, GCompare k) => Merge x k s -> EventM x (k a) -> Subscriber x a
1887+mergeSubscriber :: forall x k v s a. (HasSpiderTimeline x, GCompare k) => Merge x k v s -> EventM x (k a) -> Subscriber x (v a)
18341888mergeSubscriber m getKey = Subscriber
18351889 { subscriberPropagate = \a -> do
18361890 oldM <- liftIO $ readIORef $ _merge_accumRef m
18371891 k <- getKey
1838− let newM = DMap.insertWith (error $ "Same key fired multiple times for Merge") k (Identity a) oldM
1892+ let newM = DMap.insertWith (error $ "Same key fired multiple times for Merge") k a oldM
18391893 tracePropagate (Proxy :: Proxy x) $ " DMap.size oldM = " <> show (DMap.size oldM) <> "; DMap.size newM = " <> show (DMap.size newM)
18401894 liftIO $ writeIORef (_merge_accumRef m) $! newM
18411895 when (DMap.null oldM) $ do -- Only schedule the firing once
@@ -1850,7 +1904,7 @@ mergeSubscriber m getKey = Subscriber
18501904 else liftIO $ do
18511905#ifdef DEBUG_CYCLES
18521906 nodesInvolvedInCycle <- walkInvalidHeightParents $ eventSubscribedMerge subscribed
1853− stacks <- forM nodesInvolvedInCycle $ \(Some.This es) -> whoCreatedEventSubscribed es
1907+ stacks <- forM nodesInvolvedInCycle $ \(Some es) -> whoCreatedEventSubscribed es
18541908 let cycleInfo = ":\n" <> drawForest (listsToForest stacks)
18551909#else
18561910 let cycleInfo = ""
@@ -1866,7 +1920,7 @@ mergeSubscriber m getKey = Subscriber
18661920 }
18671921
18681922--TODO: Be able to run as much of this as possible promptly
1869−updateMerge :: (HasSpiderTimeline x, GCompare k) => Merge x k s -> MergeUpdateFunc k x p s -> p -> SomeMergeUpdate x
1923+updateMerge :: (HasSpiderTimeline x, GCompare k) => Merge x k v s -> MergeUpdateFunc k v x p s -> p -> SomeMergeUpdate x
18701924updateMerge m updateFunc p = SomeMergeUpdate updateMe (invalidateMergeHeight m) (revalidateMergeHeight m)
18711925 where updateMe = do
18721926 oldParents <- liftIO $ readIORef $ _merge_parentsRef m
@@ -1874,9 +1928,10 @@ updateMerge m updateFunc p = SomeMergeUpdate updateMe (invalidateMergeHeight m)
18741928 liftIO $ writeIORef (_merge_parentsRef m) $! newParents
18751929 return subscriptionsToKill
18761930
1877−{-# INLINE mergeCheap' #-}
1878−mergeCheap' :: forall k x p s. (HasSpiderTimeline x, GCompare k, PatchTarget p ~ DMap k (Event x)) => MergeInitFunc k x s -> MergeUpdateFunc k x p s -> MergeDestroyFunc k s -> Dynamic x p -> Event x (DMap k Identity)
1879−mergeCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
1931+{-# INLINE mergeGCheap' #-}
1932+mergeGCheap' :: forall k v x p s q. (HasSpiderTimeline x, GCompare k, PatchTarget p ~ DMap k q)
1933+ => MergeInitFunc k v q x s -> MergeUpdateFunc k v x p s -> MergeDestroyFunc k s -> DynamicS x p -> Event x (DMap k v)
1934+mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
18801935 initialParents <- readBehaviorUntracked $ dynamicCurrent d
18811936 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
18821937 heightRef <- liftIO $ newIORef $ error "merge: heightRef not yet initialized"
@@ -1924,11 +1979,11 @@ mergeCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
19241979 , occ
19251980 )
19261981
1927−mergeInt :: forall x a. (HasSpiderTimeline x) => Dynamic x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1982+mergeInt :: forall x a. (HasSpiderTimeline x) => DynamicS x (PatchIntMap (Event x a)) -> Event x (IntMap a)
19281983mergeInt = cacheEvent . mergeIntCheap
19291984
19301985{-# INLINABLE mergeIntCheap #-}
1931−mergeIntCheap :: forall x a. (HasSpiderTimeline x) => Dynamic x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1986+mergeIntCheap :: forall x a. (HasSpiderTimeline x) => DynamicS x (PatchIntMap (Event x a)) -> Event x (IntMap a)
19321987mergeIntCheap d = Event $ \sub -> do
19331988 initialParents <- readBehaviorUntracked $ dynamicCurrent d
19341989 accum <- liftIO $ FastMutableIntMap.newEmpty
@@ -2025,14 +2080,16 @@ mergeIntCheap d = Event $ \sub -> do
20252080 )
20262081
20272082newtype EventSelector x k = EventSelector { select :: forall a. k a -> Event x a }
2083+newtype EventSelectorG x k v = EventSelectorG { selectG :: forall a. k a -> Event x (v a) }
20282084
2029−fan :: (HasSpiderTimeline x, GCompare k) => Event x (DMap k Identity) -> EventSelector x k
2030−fan e =
2085+fanG :: (HasSpiderTimeline x, GCompare k) => Event x (DMap k v) -> EventSelectorG x k v
2086+fanG e = unsafePerformIO $ do
2087+ ref <- newIORef Nothing
20312088 let f = Fan
20322089 { fanParent = e
2033− , fanSubscribed = unsafeNewIORef e Nothing
2090+ , fanSubscribed = ref
20342091 }
2035− in EventSelector $ \k -> eventFan k f
2092+ pure $ EventSelectorG $ \k -> eventFan k f
20362093
20372094runHoldInits :: HasSpiderTimeline x => IORef [SomeHoldInit x] -> IORef [SomeDynInit x] -> IORef [SomeMergeInit x] -> EventM x ()
20382095runHoldInits holdInitRef dynInitRef mergeInitRef = do
@@ -2086,18 +2143,18 @@ clearEventEnv (EventEnv toAssignRef holdInitRef dynInitRef mergeUpdateRef mergeI
20862143-- | Run an event action outside of a frame
20872144runFrame :: forall x a. HasSpiderTimeline x => EventM x a -> SpiderHost x a --TODO: This function also needs to hold the mutex
20882145runFrame a = SpiderHost $ do
2089− let env = _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
2146+ let env = _spiderTimeline_eventEnv $ unSTE (spiderTimeline :: SpiderTimelineEnv x)
20902147 let go = do
20912148 result <- a
20922149 runHoldInits (eventEnvHoldInits env) (eventEnvDynInits env) (eventEnvMergeInits env) -- This must happen before doing the assignments, in case subscribing a Hold causes existing Holds to be read by the newly-propagated events
20932150 return result
20942151 result <- runEventM go
20952152 toClear <- readIORef $ eventEnvClears env
2096− forM_ toClear $ \(SomeClear ref) -> {-# SCC "clear" #-} writeIORef ref Nothing
2153+ forM_ toClear $ \(Some (Clear ref)) -> {-# SCC "clear" #-} writeIORef ref Nothing
20972154 toClearInt <- readIORef $ eventEnvIntClears env
2098− forM_ toClearInt $ \(SomeIntClear ref) -> {-# SCC "intClear" #-} writeIORef ref $! IntMap.empty
2155+ forM_ toClearInt $ \(Some (IntClear ref)) -> {-# SCC "intClear" #-} writeIORef ref $! IntMap.empty
20992156 toClearRoot <- readIORef $ eventEnvRootClears env
2100− forM_ toClearRoot $ \(SomeRootClear ref) -> {-# SCC "rootClear" #-} writeIORef ref $! DMap.empty
2157+ forM_ toClearRoot $ \(Some (RootClear ref)) -> {-# SCC "rootClear" #-} writeIORef ref $! DMap.empty
21012158 toAssign <- readIORef $ eventEnvAssignments env
21022159 toReconnectRef <- newIORef []
21032160 coincidenceInfos <- readIORef $ eventEnvResetCoincidences env
@@ -2297,7 +2354,7 @@ instance HasSpiderTimeline x => Monad (Reflex.Class.Dynamic (SpiderTimeline x))
22972354 fail _ = error "Dynamic does not support 'fail'"
22982355
22992356{-# INLINABLE newJoinDyn #-}
2300−newJoinDyn :: HasSpiderTimeline x => Reflex.Spider.Internal.Dynamic x (Identity (Reflex.Spider.Internal.Dynamic x (Identity a))) -> Reflex.Spider.Internal.Dyn x (Identity a)
2357+newJoinDyn :: HasSpiderTimeline x => DynamicS x (Identity (DynamicS x (Identity a))) -> Reflex.Spider.Internal.Dyn x (Identity a)
23012358newJoinDyn d =
23022359 let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
23032360 eOuter = Reflex.Spider.Internal.push (fmap (Just . Identity) . readBehaviorUntracked . dynamicCurrent . runIdentity) $ dynamicUpdated d
@@ -2447,7 +2504,7 @@ unsafeNewSpiderTimelineEnv = do
24472504#ifdef DEBUG
24482505 depthRef <- newIORef 0
24492506#endif
2450− return $ SpiderTimelineEnv
2507+ return $ STE $ SpiderTimelineEnv
24512508 { _spiderTimeline_lock = lock
24522509 , _spiderTimeline_eventEnv = env
24532510#ifdef DEBUG
@@ -2457,19 +2514,19 @@ unsafeNewSpiderTimelineEnv = do
24572514
24582515-- | Create a new SpiderTimelineEnv
24592516newSpiderTimeline :: IO (Some SpiderTimelineEnv)
2460−newSpiderTimeline = withSpiderTimeline (pure . Some.This)
2517+newSpiderTimeline = withSpiderTimeline (pure . Some)
24612518
2462−data LocalSpiderTimeline x s
2519+data LocalSpiderTimeline (x :: Type) s
24632520
24642521instance Reifies s (SpiderTimelineEnv x) =>
24652522 HasSpiderTimeline (LocalSpiderTimeline x s) where
2466− spiderTimeline = localSpiderTimeline (Proxy :: Proxy s) $ reflect (Proxy :: Proxy s)
2523+ spiderTimeline = localSpiderTimeline Proxy $ reflect (Proxy :: Proxy s)
24672524
24682525localSpiderTimeline
2469− :: Proxy s
2526+ :: proxy s
24702527 -> SpiderTimelineEnv x
24712528 -> SpiderTimelineEnv (LocalSpiderTimeline x s)
2472−localSpiderTimeline _ = unsafeCoerce
2529+localSpiderTimeline _ = coerce
24732530
24742531-- | Pass a new timeline to the given function.
24752532withSpiderTimeline :: (forall x. HasSpiderTimeline x => SpiderTimelineEnv x -> IO r) -> IO r
@@ -2477,18 +2534,18 @@ withSpiderTimeline k = do
24772534 env <- unsafeNewSpiderTimelineEnv
24782535 reify env $ \s -> k $ localSpiderTimeline s env
24792536
2480−newtype SpiderPullM x a = SpiderPullM (BehaviorM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
2537+newtype SpiderPullM (x :: Type) a = SpiderPullM (BehaviorM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
24812538
24822539type ComputeM = EventM
24832540
2484−newtype SpiderPushM x a = SpiderPushM (ComputeM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
2541+newtype SpiderPushM (x :: Type) a = SpiderPushM (ComputeM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
24852542
24862543instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
24872544 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
24882545 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
24892546 newtype Event (SpiderTimeline x) a = SpiderEvent { unSpiderEvent :: Event x a }
2490− newtype Dynamic (SpiderTimeline x) a = SpiderDynamic { unSpiderDynamic :: Dynamic x (Identity a) } -- deriving (Functor, Applicative, Monad)
2491− newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: Dynamic x p }
2547+ newtype Dynamic (SpiderTimeline x) a = SpiderDynamic { unSpiderDynamic :: DynamicS x (Identity a) } -- deriving (Functor, Applicative, Monad)
2548+ newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: DynamicS x p }
24922549 type PullM (SpiderTimeline x) = SpiderPullM x
24932550 type PushM (SpiderTimeline x) = SpiderPushM x
24942551 {-# INLINABLE never #-}
@@ -2501,10 +2558,15 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
25012558 pushCheap f = SpiderEvent . pushCheap (coerce f) . unSpiderEvent
25022559 {-# INLINABLE pull #-}
25032560 pull = SpiderBehavior . pull . coerce
2504− {-# INLINABLE merge #-}
2505− merge = SpiderEvent . merge . dynamicConst . (coerce :: DMap k (R.Event (SpiderTimeline x)) -> DMap k (Event x))
2506− {-# INLINABLE fan #-}
2507− fan e = R.EventSelector $ SpiderEvent . select (fan (unSpiderEvent e))
2561+ {-# INLINABLE fanG #-}
2562+ fanG e = R.EventSelectorG $ SpiderEvent . selectG (fanG (unSpiderEvent e))
2563+ {-# INLINABLE mergeG #-}
2564+ mergeG
2565+ :: forall (k :: k2 -> *) q (v :: k2 -> *). GCompare k
2566+ => (forall a. q a -> R.Event (SpiderTimeline x) (v a))
2567+ -> DMap k q
2568+ -> R.Event (SpiderTimeline x) (DMap k v)
2569+ mergeG nt = SpiderEvent . mergeG (unSpiderEvent #. nt) . dynamicConst
25082570 {-# INLINABLE switch #-}
25092571 switch = SpiderEvent . switch . (coerce :: Behavior x (R.Event (SpiderTimeline x) a) -> Behavior x (Event x a)) . unSpiderBehavior
25102572 {-# INLINABLE coincidence #-}
@@ -2512,15 +2574,15 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
25122574 {-# INLINABLE current #-}
25132575 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
25142576 {-# INLINABLE updated #-}
2515− updated = coerce $ SpiderEvent . dynamicUpdated . unSpiderDynamic
2577+ updated = SpiderEvent #. dynamicUpdated .# fmap coerce . unSpiderDynamic
25162578 {-# INLINABLE unsafeBuildDynamic #-}
25172579 unsafeBuildDynamic readV0 v' = SpiderDynamic $ dynamicDynIdentity $ unsafeBuildDynamic (coerce readV0) $ coerce $ unSpiderEvent v'
25182580 {-# INLINABLE unsafeBuildIncremental #-}
25192581 unsafeBuildIncremental readV0 dv = SpiderIncremental $ dynamicDyn $ unsafeBuildDynamic (coerce readV0) $ unSpiderEvent dv
2520− {-# INLINABLE mergeIncremental #-}
2521− mergeIncremental = SpiderEvent . merge . (unsafeCoerce :: Dynamic x (PatchDMap k (R.Event (SpiderTimeline x))) -> Dynamic x (PatchDMap k (Event x))) . unSpiderIncremental
2522− {-# INLINABLE mergeIncrementalWithMove #-}
2523− mergeIncrementalWithMove = SpiderEvent . mergeWithMove . (unsafeCoerce :: Dynamic x (PatchDMapWithMove k (R.Event (SpiderTimeline x))) -> Dynamic x (PatchDMapWithMove k (Event x))) . unSpiderIncremental
2582+ {-# INLINABLE mergeIncrementalG #-}
2583+ mergeIncrementalG nt = SpiderEvent #. mergeG (coerce #. nt) .# unSpiderIncremental
2584+ {-# INLINABLE mergeIncrementalWithMoveG #-}
2585+ mergeIncrementalWithMoveG nt = SpiderEvent #. mergeWithMove (coerce #. nt) .# unSpiderIncremental
25242586 {-# INLINABLE currentIncremental #-}
25252587 currentIncremental = SpiderBehavior . dynamicCurrent . unSpiderIncremental
25262588 {-# INLINABLE updatedIncremental #-}
@@ -2531,9 +2593,10 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
25312593 return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
25322594 eventCoercion Coercion = Coercion
25332595 behaviorCoercion Coercion = Coercion
2534− dynamicCoercion = unsafeCoerce --TODO: How can we avoid this unsafeCoerce? This is safe only because we know how Identity works as a Patch instance
2596+ dynamicCoercion Coercion = Coercion
2597+ incrementalCoercion Coercion Coercion = Coercion
25352598 {-# INLINABLE mergeIntIncremental #-}
2536− mergeIntIncremental = SpiderEvent . mergeInt . (unsafeCoerce :: Dynamic x (PatchIntMap (R.Event (SpiderTimeline x) a)) -> Dynamic x (PatchIntMap (Event x a))) . unSpiderIncremental
2599+ mergeIntIncremental = SpiderEvent . mergeInt . coerce
25372600 {-# INLINABLE fanInt #-}
25382601 fanInt e = R.EventSelectorInt $ SpiderEvent . selectInt (fanInt (unSpiderEvent e))
25392602
@@ -2558,7 +2621,7 @@ instance MonadAtomicRef (EventM x) where
25582621 atomicModifyRef r f = liftIO $ atomicModifyRef r f
25592622
25602623-- | The monad for actions that manipulate a Spider timeline identified by @x@
2561−newtype SpiderHost x a = SpiderHost { unSpiderHost :: IO a } deriving (Functor, Applicative, MonadFix, MonadIO, MonadException, MonadAsyncException)
2624+newtype SpiderHost (x :: Type) a = SpiderHost { unSpiderHost :: IO a } deriving (Functor, Applicative, MonadFix, MonadIO, MonadException, MonadAsyncException)
25622625
25632626instance Monad (SpiderHost x) where
25642627 {-# INLINABLE (>>=) #-}
@@ -2580,7 +2643,7 @@ runSpiderHost (SpiderHost a) = a
25802643runSpiderHostForTimeline :: SpiderHost x a -> SpiderTimelineEnv x -> IO a
25812644runSpiderHostForTimeline (SpiderHost a) _ = a
25822645
2583−newtype SpiderHostFrame x a = SpiderHostFrame { runSpiderHostFrame :: EventM x a }
2646+newtype SpiderHostFrame (x :: Type) a = SpiderHostFrame { runSpiderHostFrame :: EventM x a }
25842647 deriving (Functor, Applicative, MonadFix, MonadIO, MonadException, MonadAsyncException)
25852648
25862649instance Monad (SpiderHostFrame x) where