@@ -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 #-}
@@ -18,6 +17,8 @@
1817{-# LANGUAGE TypeOperators #-}
1918{-# LANGUAGE UndecidableInstances #-}
2019{-# LANGUAGE PolyKinds #-}
20+{-# LANGUAGE DeriveFunctor #-}
21+{-# LANGUAGE StandaloneDeriving #-}
2122{-# LANGUAGE InstanceSigs #-}
2223
2324#ifdef USE_REFLEX_OPTIMIZER
@@ -37,7 +38,10 @@ import Control.Monad hiding (forM, forM_, mapM, mapM_)
3738import Control.Monad.Exception
3839import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
3940import Control.Monad.Primitive
40−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
4145import Control.Monad.Ref
4246import Data.Align
4347import Data.Coerce
@@ -68,6 +72,12 @@ import System.IO.Unsafe
6872import System.Mem.Weak
6973import Unsafe.Coerce
7074
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+
7181#ifdef DEBUG_CYCLES
7282import Control.Monad.State hiding (forM, forM_, mapM, mapM_, sequence)
7383import Data.List.NonEmpty (NonEmpty (..), nonEmpty)
@@ -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
@@ -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
@@ -703,42 +718,46 @@ readBehaviorUntracked b = do
703718-- Dynamic
704719--------------------------------------------------------------------------------
705720
706−data Dynamic x p = Dynamic
707− { dynamicCurrent :: !(Behavior x (PatchTarget p))
721+type DynamicS x p = Dynamic x (PatchTarget p) p
722+
723+data Dynamic x target p = Dynamic
724+ { dynamicCurrent :: !(Behavior x target)
708725 , 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
@@ -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])
@@ -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 (>>=) #-}
@@ -1139,17 +1163,21 @@ instance HasSpiderTimeline x => Semialign (Event x) where
11391163 align ea eb = mapMaybe dmapToThese $ mergeG coerce $ dynamicConst $
11401164 DMap.fromDistinctAscList [LeftTag :=> ea, RightTag :=> eb]
11411165
1166+#if defined(MIN_VERSION_semialign)
1167+ zip x y = mapMaybe justThese $ align x y
1168+#endif
1169+
11421170data DynType x p = UnsafeDyn !(BehaviorM x (PatchTarget p), Event x p)
11431171 | BuildDyn !(EventM x (PatchTarget p), Event x p)
11441172 | HoldDyn !(Hold x p)
11451173
11461174newtype Dyn (x :: Type) p = Dyn { unDyn :: IORef (DynType x p) }
11471175
1148−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)
11491177newMapDyn f d = dynamicDynIdentity $ unsafeBuildDynamic (fmap f $ readBehaviorTracked $ dynamicCurrent d) (Identity . f . runIdentity <$> dynamicUpdated d)
11501178
11511179--TODO: Avoid the duplication between this and R.zipDynWith
1152−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)
11531181zipDynWith f da db =
11541182 let eab = align (dynamicUpdated da) (dynamicUpdated db)
11551183 ec = flip push eab $ \o -> do
@@ -1225,7 +1253,7 @@ run :: forall x b. HasSpiderTimeline x => [DSum (RootTrigger x) Identity] -> Res
12251253run roots after = do
12261254 tracePropagate (Proxy :: Proxy x) $ "Running an event frame with " <> show (length roots) <> " events"
12271255 let t = spiderTimeline :: SpiderTimelineEnv x
1228− result <- SpiderHost $ withMVar (_spiderTimeline_lock t) $ \_ -> unSpiderHost $ runFrame $ do
1256+ result <- SpiderHost $ withMVar (_spiderTimeline_lock (unSTE t)) $ \_ -> unSpiderHost $ runFrame $ do
12291257 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
12301258 occBefore <- liftIO $ do
12311259 occBefore <- readIORef occRef
@@ -1289,9 +1317,9 @@ type WeakList a = [Weak a]
12891317withIncreasedDepth :: CanTrace x m => m a -> m a
12901318withIncreasedDepth a = do
12911319 spiderTimeline <- askSpiderTimelineEnv
1292− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) succ
1320+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) succ
12931321 result <- a
1294− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) pred
1322+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) pred
12951323 return result
12961324#else
12971325withIncreasedDepth :: m a -> m a
@@ -1318,7 +1346,7 @@ traceMWhen _ b getMessage = when b $ do
13181346 message <- getMessage
13191347#ifdef DEBUG
13201348 spiderTimeline <- askSpiderTimelineEnv
1321− d <- liftIO $ readIORef $ _spiderTimeline_depth spiderTimeline
1349+ d <- liftIO $ readIORef $ _spiderTimeline_depth $ unSTE spiderTimeline
13221350#else
13231351 let d = 0
13241352#endif
@@ -1359,25 +1387,25 @@ propagateSubscriberHold h a = do
13591387data SomeResetCoincidence x = forall a. SomeResetCoincidence !(EventSubscription x) !(Maybe (CoincidenceSubscribed x a)) -- The CoincidenceSubscriber will be present only if heights need to be reset
13601388
13611389runBehaviorM :: BehaviorM x a -> Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]) -> IORef [SomeHoldInit x] -> IO a
1362−runBehaviorM a mwi holdInits = runReaderT (unBehaviorM a) (mwi, holdInits)
1390+runBehaviorM a mwi holdInits = runReaderIO (unBehaviorM a) (mwi, holdInits)
13631391
13641392askInvalidator :: BehaviorM x (Maybe (Weak (Invalidator x)))
13651393askInvalidator = do
1366− (!m, _) <- BehaviorM ask
1394+ (!m, _) <- ask
13671395 case m of
13681396 Nothing -> return Nothing
13691397 Just (!wi, _) -> return $ Just wi
13701398
13711399askParentsRef :: BehaviorM x (Maybe (IORef [SomeBehaviorSubscribed x]))
13721400askParentsRef = do
1373− (!m, _) <- BehaviorM ask
1401+ (!m, _) <- ask
13741402 case m of
13751403 Nothing -> return Nothing
13761404 Just (_, !p) -> return $ Just p
13771405
13781406askBehaviorHoldInits :: BehaviorM x (IORef [SomeHoldInit x])
13791407askBehaviorHoldInits = do
1380− (_, !his) <- BehaviorM ask
1408+ (_, !his) <- ask
13811409 return his
13821410
13831411{-# INLINE getDynHold #-}
@@ -1701,20 +1729,20 @@ subscribeCoincidenceSubscribed subscribed sub = WeakBag.insert sub (coincidenceS
17011729{-# INLINE mergeG #-}
17021730mergeG :: forall k q x v. (HasSpiderTimeline x, GCompare k)
17031731 => (forall a. q a -> Event x (v a))
1704− -> Dynamic x (PatchDMap k q) -> Event x (DMap k v)
1732+ -> DynamicS x (PatchDMap k q) -> Event x (DMap k v)
17051733mergeG nt d = cacheEvent (mergeCheap nt d)
17061734
17071735{-# INLINE mergeWithMove #-}
17081736mergeWithMove :: forall k v q x. (HasSpiderTimeline x, GCompare k)
17091737 => (forall a. q a -> Event x (v a))
1710− -> Dynamic x (PatchDMapWithMove k q) -> Event x (DMap k v)
1738+ -> DynamicS x (PatchDMapWithMove k q) -> Event x (DMap k v)
17111739mergeWithMove nt d = cacheEvent (mergeCheapWithMove nt d)
17121740
17131741{-# INLINE [1] mergeCheap #-}
17141742mergeCheap
17151743 :: forall k x q v. (HasSpiderTimeline x, GCompare k)
17161744 => (forall a. q a -> Event x (v a))
1717− -> Dynamic x (PatchDMap k q)
1745+ -> DynamicS x (PatchDMap k q)
17181746 -> Event x (DMap k v)
17191747mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
17201748 where
@@ -1742,7 +1770,7 @@ mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
17421770 let s = subscriber $ return k
17431771 (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead (nt e) s
17441772 height <- liftIO $ getEventSubscribedHeight parentSubd
1745− return (fmap (\x -> k :=> x) parentOcc, height, k :=> MergeSubscribedParent subscription)
1773+ return (fmap (k :=>) parentOcc, height, k :=> MergeSubscribedParent subscription)
17461774 return ( DMap.fromDistinctAscList $ mapMaybe (\(x, _, _) -> x) subscribers
17471775 , fmap (\(_, h, _) -> h) subscribers --TODO: Assert that there's no invalidHeight in here
17481776 , DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
@@ -1754,7 +1782,7 @@ mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
17541782{-# INLINE [1] mergeCheapWithMove #-}
17551783mergeCheapWithMove :: forall k x v q. (HasSpiderTimeline x, GCompare k)
17561784 => (forall a. q a -> Event x (v a))
1757− -> Dynamic x (PatchDMapWithMove k q)
1785+ -> DynamicS x (PatchDMapWithMove k q)
17581786 -> Event x (DMap k v)
17591787mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
17601788 where
@@ -1790,7 +1818,7 @@ mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
17901818 let s = subscriber $ liftIO $ readIORef keyRef
17911819 (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead (nt e) s
17921820 height <- liftIO $ getEventSubscribedHeight parentSubd
1793− return (fmap (\x -> k :=> x) parentOcc, height, k :=> MergeSubscribedParentWithMove subscription keyRef)
1821+ return (fmap (k :=>) parentOcc, height, k :=> MergeSubscribedParentWithMove subscription keyRef)
17941822 return ( DMap.fromDistinctAscList $ mapMaybe (\(x, _, _) -> x) subscribers
17951823 , fmap (\(_, h, _) -> h) subscribers --TODO: Assert that there's no invalidHeight in here
17961824 , DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
@@ -1902,7 +1930,7 @@ updateMerge m updateFunc p = SomeMergeUpdate updateMe (invalidateMergeHeight m)
19021930
19031931{-# INLINE mergeGCheap' #-}
19041932mergeGCheap' :: forall k v x p s q. (HasSpiderTimeline x, GCompare k, PatchTarget p ~ DMap k q)
1905− => MergeInitFunc k v q x s -> MergeUpdateFunc k v x p s -> MergeDestroyFunc k s -> Dynamic x p -> Event x (DMap k v)
1933+ => MergeInitFunc k v q x s -> MergeUpdateFunc k v x p s -> MergeDestroyFunc k s -> DynamicS x p -> Event x (DMap k v)
19061934mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
19071935 initialParents <- readBehaviorUntracked $ dynamicCurrent d
19081936 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
@@ -1951,11 +1979,11 @@ mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
19511979 , occ
19521980 )
19531981
1954−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)
19551983mergeInt = cacheEvent . mergeIntCheap
19561984
19571985{-# INLINABLE mergeIntCheap #-}
1958−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)
19591987mergeIntCheap d = Event $ \sub -> do
19601988 initialParents <- readBehaviorUntracked $ dynamicCurrent d
19611989 accum <- liftIO $ FastMutableIntMap.newEmpty
@@ -2115,7 +2143,7 @@ clearEventEnv (EventEnv toAssignRef holdInitRef dynInitRef mergeUpdateRef mergeI
21152143-- | Run an event action outside of a frame
21162144runFrame :: forall x a. HasSpiderTimeline x => EventM x a -> SpiderHost x a --TODO: This function also needs to hold the mutex
21172145runFrame a = SpiderHost $ do
2118− let env = _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
2146+ let env = _spiderTimeline_eventEnv $ unSTE (spiderTimeline :: SpiderTimelineEnv x)
21192147 let go = do
21202148 result <- a
21212149 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
@@ -2326,7 +2354,7 @@ instance HasSpiderTimeline x => Monad (Reflex.Class.Dynamic (SpiderTimeline x))
23262354 fail _ = error "Dynamic does not support 'fail'"
23272355
23282356{-# INLINABLE newJoinDyn #-}
2329−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)
23302358newJoinDyn d =
23312359 let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
23322360 eOuter = Reflex.Spider.Internal.push (fmap (Just . Identity) . readBehaviorUntracked . dynamicCurrent . runIdentity) $ dynamicUpdated d
@@ -2476,7 +2504,7 @@ unsafeNewSpiderTimelineEnv = do
24762504#ifdef DEBUG
24772505 depthRef <- newIORef 0
24782506#endif
2479− return $ SpiderTimelineEnv
2507+ return $ STE $ SpiderTimelineEnv
24802508 { _spiderTimeline_lock = lock
24812509 , _spiderTimeline_eventEnv = env
24822510#ifdef DEBUG
@@ -2492,13 +2520,13 @@ data LocalSpiderTimeline (x :: Type) s
24922520
24932521instance Reifies s (SpiderTimelineEnv x) =>
24942522 HasSpiderTimeline (LocalSpiderTimeline x s) where
2495− spiderTimeline = localSpiderTimeline (Proxy :: Proxy s) $ reflect (Proxy :: Proxy s)
2523+ spiderTimeline = localSpiderTimeline Proxy $ reflect (Proxy :: Proxy s)
24962524
24972525localSpiderTimeline
2498− :: Proxy s
2526+ :: proxy s
24992527 -> SpiderTimelineEnv x
25002528 -> SpiderTimelineEnv (LocalSpiderTimeline x s)
2501−localSpiderTimeline _ = unsafeCoerce
2529+localSpiderTimeline _ = coerce
25022530
25032531-- | Pass a new timeline to the given function.
25042532withSpiderTimeline :: (forall x. HasSpiderTimeline x => SpiderTimelineEnv x -> IO r) -> IO r
@@ -2516,8 +2544,8 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
25162544 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
25172545 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
25182546 newtype Event (SpiderTimeline x) a = SpiderEvent { unSpiderEvent :: Event x a }
2519− newtype Dynamic (SpiderTimeline x) a = SpiderDynamic { unSpiderDynamic :: Dynamic x (Identity a) } -- deriving (Functor, Applicative, Monad)
2520− 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 }
25212549 type PullM (SpiderTimeline x) = SpiderPullM x
25222550 type PushM (SpiderTimeline x) = SpiderPushM x
25232551 {-# INLINABLE never #-}
@@ -2546,7 +2574,7 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
25462574 {-# INLINABLE current #-}
25472575 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
25482576 {-# INLINABLE updated #-}
2549− updated = coerce $ SpiderEvent . dynamicUpdated . unSpiderDynamic
2577+ updated = SpiderEvent #. dynamicUpdated .# fmap coerce . unSpiderDynamic
25502578 {-# INLINABLE unsafeBuildDynamic #-}
25512579 unsafeBuildDynamic readV0 v' = SpiderDynamic $ dynamicDynIdentity $ unsafeBuildDynamic (coerce readV0) $ coerce $ unSpiderEvent v'
25522580 {-# INLINABLE unsafeBuildIncremental #-}
@@ -2565,9 +2593,10 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
25652593 return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
25662594 eventCoercion Coercion = Coercion
25672595 behaviorCoercion Coercion = Coercion
2568− 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
25692598 {-# INLINABLE mergeIntIncremental #-}
2570− mergeIntIncremental = SpiderEvent . mergeInt . (unsafeCoerce :: Dynamic x (PatchIntMap (R.Event (SpiderTimeline x) a)) -> Dynamic x (PatchIntMap (Event x a))) . unSpiderIncremental
2599+ mergeIntIncremental = SpiderEvent . mergeInt . coerce
25712600 {-# INLINABLE fanInt #-}
25722601 fanInt e = R.EventSelectorInt $ SpiderEvent . selectInt (fanInt (unSpiderEvent e))
25732602