on develop help sign in
Revert "Generalize fan following DMap (#318)"
04403d3Matthew Bauer
ChangeLog.md−4
@@ -16,16 +16,12 @@
16
16
17## 0.6.2.1
17## 0.6.2.1
18
18
19−* Generalize `fan` to `fanG` to take a `DMap` with non-`Identity`
20− values.
21−
22* Generalize merging functions:
19* Generalize merging functions:
23 `merge` to `mergeG`,
20 `merge` to `mergeG`,
24 `mergeIncremental` to `mergeIncrementalG`,
21 `mergeIncremental` to `mergeIncrementalG`,
25 `distributeDMapOverDynPure` to `distributeDMapOverDynPureG`,
22 `distributeDMapOverDynPure` to `distributeDMapOverDynPureG`,
26 `mergeIncrementalWithMove` to `mergeIncrementalWithMoveG`.
23 `mergeIncrementalWithMove` to `mergeIncrementalWithMoveG`.
27
24
28−
29## 0.6.2.0
25## 0.6.2.0
30
26
31* Fix `holdDyn` so that it is lazy in its event argument
27* Fix `holdDyn` so that it is lazy in its event argument
src/Reflex/Class.hs+3−31
@@ -41,7 +41,6 @@ module Reflex.Class
41 , MonadHold (..)
41 , MonadHold (..)
42 -- ** 'fan' related types
42 -- ** 'fan' related types
43 , EventSelector (..)
43 , EventSelector (..)
44− , EventSelectorG (..)
45 , EventSelectorInt (..)
44 , EventSelectorInt (..)
46 -- * Convenience functions
45 -- * Convenience functions
47 , constDyn
46 , constDyn
@@ -65,7 +64,6 @@ module Reflex.Class
65 , alignEventWithMaybe
64 , alignEventWithMaybe
66 -- ** Breaking up 'Event's
65 -- ** Breaking up 'Event's
67 , splitE
66 , splitE
68− , fan
69 , fanEither
67 , fanEither
70 , fanThese
68 , fanThese
71 , fanMap
69 , fanMap
@@ -273,16 +271,13 @@ class ( MonadHold t (PushM t)
273 -- | Merge a collection of events; the resulting 'Event' will only occur if at
271 -- | Merge a collection of events; the resulting 'Event' will only occur if at
274 -- least one input event is occurring, and will contain all of the input keys
272 -- least one input event is occurring, and will contain all of the input keys
275 -- that are occurring simultaneously
273 -- that are occurring simultaneously
276−
277− --TODO: Generalize to get rid of DMap use --TODO: Provide a type-level guarantee that the result is not empty
278 mergeG :: GCompare k => (forall a. q a -> Event t (v a))
274 mergeG :: GCompare k => (forall a. q a -> Event t (v a))
279 -> DMap k q -> Event t (DMap k v)
275 -> DMap k q -> Event t (DMap k v)
280−
276+ --TODO: Generalize to get rid of DMap use --TODO: Provide a type-level guarantee that the result is not empty
281 -- | Efficiently fan-out an event to many destinations. You should save the
277 -- | Efficiently fan-out an event to many destinations. You should save the
282− -- result in a @let@-binding, and then repeatedly 'selectG' on the result to
278+ -- result in a @let@-binding, and then repeatedly 'select' on the result to
283 -- create child events
279 -- create child events
284− fanG :: GCompare k => Event t (DMap k v) -> EventSelectorG t k v
280+ fan :: GCompare k => Event t (DMap k Identity) -> EventSelector t k
285−
286 -- | Create an 'Event' that will occur whenever the currently-selected input
281 -- | Create an 'Event' that will occur whenever the currently-selected input
287 -- 'Event' occurs
282 -- 'Event' occurs
288 switch :: Behavior t (Event t a) -> Event t a
283 switch :: Behavior t (Event t a) -> Event t a
@@ -330,18 +325,6 @@ class ( MonadHold t (PushM t)
330 mergeIntIncremental :: Incremental t (PatchIntMap (Event t a)) -> Event t (IntMap a)
325 mergeIntIncremental :: Incremental t (PatchIntMap (Event t a)) -> Event t (IntMap a)
331 fanInt :: Event t (IntMap a) -> EventSelectorInt t a
326 fanInt :: Event t (IntMap a) -> EventSelectorInt t a
332
327
333−-- | Efficiently fan-out an event to many destinations. You should save the
334−-- result in a @let@-binding, and then repeatedly 'select' on the result to
335−-- create child events
336−fan :: forall t k. (Reflex t, GCompare k)
337− => Event t (DMap k Identity) -> EventSelector t k
338− --TODO: Can we help enforce the partial application discipline here? The combinator is worthless without it
339−fan e = EventSelector (fixup (selectG (fanG e) :: k a -> Event t (Identity a)) :: forall a. k a -> Event t a)
340− where
341− fixup :: forall a. (k a -> Event t (Identity a)) -> k a -> Event t a
342− fixup = case eventCoercion Coercion :: Coercion (Event t (Identity a)) (Event t a) of
343− Coercion -> coerce
344−
345--TODO: Specialize this so that we can take advantage of knowing that there's no changing going on
328--TODO: Specialize this so that we can take advantage of knowing that there's no changing going on
346-- | Constructs a single 'Event' out of a map of events. The output event may fire with multiple
329-- | Constructs a single 'Event' out of a map of events. The output event may fire with multiple
347-- keys simultaneously.
330-- keys simultaneously.
@@ -535,17 +518,6 @@ newtype EventSelector t k = EventSelector
535 select :: forall a. k a -> Event t a
518 select :: forall a. k a -> Event t a
536 }
519 }
537
520
538−newtype EventSelectorG t k v = EventSelectorG
539− { -- | Retrieve the 'Event' for the given key. The type of the 'Event' is
540− -- determined by the type of the key, so this can be used to fan-out
541− -- 'Event's whose sub-'Event's have different types.
542− --
543− -- Using 'EventSelector's and the 'fan' primitive is far more efficient than
544− -- (but equivalent to) using 'mapMaybe' to select only the relevant
545− -- occurrences of an 'Event'.
546− selectG :: forall a. k a -> Event t (v a)
547− }
548−
549-- | Efficiently select an 'Event' keyed on 'Int'. This is more efficient than manually
521-- | Efficiently select an 'Event' keyed on 'Int'. This is more efficient than manually
550-- filtering by key.
522-- filtering by key.
551newtype EventSelectorInt t a = EventSelectorInt { selectInt :: Int -> Event t a }
523newtype EventSelectorInt t a = EventSelectorInt { selectInt :: Int -> Event t a }
src/Reflex/Profiled.hs+1−1
@@ -136,11 +136,11 @@ instance Reflex t => Reflex (ProfiledTimeline t) where
136 push f (Event_Profiled e) = coerce $ push (coerce f) $ profileEvent e -- Profile before rather than after; this way fanout won't count against us
136 push f (Event_Profiled e) = coerce $ push (coerce f) $ profileEvent e -- Profile before rather than after; this way fanout won't count against us
137 pushCheap f (Event_Profiled e) = coerce $ pushCheap (coerce f) $ profileEvent e
137 pushCheap f (Event_Profiled e) = coerce $ pushCheap (coerce f) $ profileEvent e
138 pull = Behavior_Profiled . pull . coerce
138 pull = Behavior_Profiled . pull . coerce
139− fanG (Event_Profiled e) = EventSelectorG $ coerce $ selectG (fanG $ profileEvent e)
140 mergeG :: forall (k :: z -> *) q v. GCompare k
139 mergeG :: forall (k :: z -> *) q v. GCompare k
141 => (forall a. q a -> Event (ProfiledTimeline t) (v a))
140 => (forall a. q a -> Event (ProfiledTimeline t) (v a))
142 -> DMap k q -> Event (ProfiledTimeline t) (DMap k v)
141 -> DMap k q -> Event (ProfiledTimeline t) (DMap k v)
143 mergeG nt = Event_Profiled #. mergeG (coerce nt)
142 mergeG nt = Event_Profiled #. mergeG (coerce nt)
143+ fan (Event_Profiled e) = EventSelector $ coerce $ select (fan $ profileEvent e)
144 switch (Behavior_Profiled b) = coerce $ profileEvent $ switch (coerceBehavior b)
144 switch (Behavior_Profiled b) = coerce $ profileEvent $ switch (coerceBehavior b)
145 coincidence (Event_Profiled e) = coerce $ profileEvent $ coincidence (coerceEvent e)
145 coincidence (Event_Profiled e) = coerce $ profileEvent $ coincidence (coerceEvent e)
146 current (Dynamic_Profiled d) = coerce $ current d
146 current (Dynamic_Profiled d) = coerce $ current d
src/Reflex/Pure.hs+3−3
@@ -7,7 +7,6 @@
7{-# LANGUAGE TypeFamilies #-}
7{-# LANGUAGE TypeFamilies #-}
8{-# LANGUAGE RankNTypes #-}
8{-# LANGUAGE RankNTypes #-}
9{-# LANGUAGE PolyKinds #-}
9{-# LANGUAGE PolyKinds #-}
10−
11#ifdef USE_REFLEX_OPTIMIZER
10#ifdef USE_REFLEX_OPTIMIZER
12{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
11{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
13#endif
12#endif
@@ -34,6 +33,7 @@ module Reflex.Pure
34import Control.Monad
33import Control.Monad
35import Data.Dependent.Map (DMap, GCompare)
34import Data.Dependent.Map (DMap, GCompare)
36import qualified Data.Dependent.Map as DMap
35import qualified Data.Dependent.Map as DMap
36+import Data.Functor.Identity
37import Data.IntMap (IntMap)
37import Data.IntMap (IntMap)
38import qualified Data.IntMap as IntMap
38import qualified Data.IntMap as IntMap
39import Data.Maybe
39import Data.Maybe
@@ -88,8 +88,8 @@ instance (Enum t, HasTrie t, Ord t) => Reflex (Pure t) where
88 then Nothing
88 then Nothing
89 else Just currentOccurrences
89 else Just currentOccurrences
90
90
91− -- fanG :: GCompare k => Event (Pure t) (DMap k v) -> EventSelectorG (Pure t) k v
91+ fan :: GCompare k => Event (Pure t) (DMap k Identity) -> EventSelector (Pure t) k
92− fanG e = EventSelectorG $ \k -> Event $ \t -> unEvent e t >>= DMap.lookup k
92+ fan e = EventSelector $ \k -> Event $ \t -> unEvent e t >>= fmap runIdentity . DMap.lookup k
93
93
94 switch :: Behavior (Pure t) (Event (Pure t) a) -> Event (Pure t) a
94 switch :: Behavior (Pure t) (Event (Pure t) a) -> Event (Pure t) a
95 switch b = Event $ memo $ \t -> unEvent (unBehavior b t) t
95 switch b = Event $ memo $ \t -> unEvent (unBehavior b t) t
src/Reflex/Spider/Internal.hs+24−26
@@ -20,7 +20,6 @@
20{-# LANGUAGE DeriveFunctor #-}
20{-# LANGUAGE DeriveFunctor #-}
21{-# LANGUAGE StandaloneDeriving #-}
21{-# LANGUAGE StandaloneDeriving #-}
22{-# LANGUAGE InstanceSigs #-}
22{-# LANGUAGE InstanceSigs #-}
23−
24#ifdef USE_REFLEX_OPTIMIZER
23#ifdef USE_REFLEX_OPTIMIZER
25{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
24{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
26#endif
25#endif
@@ -388,7 +387,7 @@ eventRoot !k !r = Event $ wrap eventSubscribedRoot $ liftIO . getRootSubscribed
388eventNever :: Event x a
387eventNever :: Event x a
389eventNever = Event $ \_ -> return (EventSubscription (return ()) eventSubscribedNever, Nothing)
388eventNever = Event $ \_ -> return (EventSubscription (return ()) eventSubscribedNever, Nothing)
390
389
391−eventFan :: (GCompare k, HasSpiderTimeline x) => k a -> Fan x k v -> Event x (v a)
390+eventFan :: (GCompare k, HasSpiderTimeline x) => k a -> Fan x k -> Event x a
392eventFan !k !f = Event $ wrap eventSubscribedFan $ getFanSubscribed k f
391eventFan !k !f = Event $ wrap eventSubscribedFan $ getFanSubscribed k f
393
392
394eventSwitch :: HasSpiderTimeline x => Switch x a -> Event x a
393eventSwitch :: HasSpiderTimeline x => Switch x a -> Event x a
@@ -440,14 +439,14 @@ newSubscriberHold h = return $ Subscriber
440 , subscriberRecalculateHeight = \_ -> return ()
439 , subscriberRecalculateHeight = \_ -> return ()
441 }
440 }
442
441
443−newSubscriberFan :: forall x k v. (HasSpiderTimeline x, GCompare k) => FanSubscribed x k v -> IO (Subscriber x (DMap k v))
442+newSubscriberFan :: forall x k. (HasSpiderTimeline x, GCompare k) => FanSubscribed x k -> IO (Subscriber x (DMap k Identity))
444newSubscriberFan subscribed = return $ Subscriber
443newSubscriberFan subscribed = return $ Subscriber
445 { subscriberPropagate = \a -> {-# SCC "traverseFan" #-} do
444 { subscriberPropagate = \a -> {-# SCC "traverseFan" #-} do
446 subs <- liftIO $ readIORef $ fanSubscribedSubscribers subscribed
445 subs <- liftIO $ readIORef $ fanSubscribedSubscribers subscribed
447 tracePropagate (Proxy :: Proxy x) $ "SubscriberFan" <> showNodeId subscribed <> ": " ++ show (DMap.size subs) ++ " keys subscribed, " ++ show (DMap.size a) ++ " keys firing"
446 tracePropagate (Proxy :: Proxy x) $ "SubscriberFan" <> showNodeId subscribed <> ": " ++ show (DMap.size subs) ++ " keys subscribed, " ++ show (DMap.size a) ++ " keys firing"
448 liftIO $ writeIORef (fanSubscribedOccurrence subscribed) $ Just a
447 liftIO $ writeIORef (fanSubscribedOccurrence subscribed) $ Just a
449 scheduleClear $ fanSubscribedOccurrence subscribed
448 scheduleClear $ fanSubscribedOccurrence subscribed
450− let f _ (Pair v subsubs) = do
449+ let f _ (Pair (Identity v) subsubs) = do
451 propagate v $ _fanSubscribedChildren_list subsubs
450 propagate v $ _fanSubscribedChildren_list subsubs
452 return $ Constant ()
451 return $ Constant ()
453 _ <- DMap.traverseWithKey f $ DMap.intersectionWithKey (\_ -> Pair) a subs --TODO: Would be nice to have DMap.traverse_
452 _ <- DMap.traverseWithKey f $ DMap.intersectionWithKey (\_ -> Pair) a subs --TODO: Would be nice to have DMap.traverse_
@@ -600,7 +599,7 @@ eventSubscribedNever = EventSubscribed
600#endif
599#endif
601 }
600 }
602
601
603−eventSubscribedFan :: FanSubscribed x k v -> EventSubscribed x
602+eventSubscribedFan :: FanSubscribed x k -> EventSubscribed x
604eventSubscribedFan !subscribed = EventSubscribed
603eventSubscribedFan !subscribed = EventSubscribed
605 { eventSubscribedHeightRef = eventSubscribedHeightRef $ _eventSubscription_subscribed $ fanSubscribedParent subscribed
604 { eventSubscribedHeightRef = eventSubscribedHeightRef $ _eventSubscription_subscribed $ fanSubscribedParent subscribed
606 , eventSubscribedRetained = toAny subscribed
605 , eventSubscribedRetained = toAny subscribed
@@ -1018,7 +1017,7 @@ data RootSubscribed x a = forall k. GCompare k => RootSubscribed
1018#endif
1017#endif
1019 }
1018 }
1020
1019
1021−data Root x k
1020+data Root x (k :: * -> *)
1022 = Root { rootOccurrence :: !(IORef (DMap k Identity)) -- The currently-firing occurrence of this event
1021 = Root { rootOccurrence :: !(IORef (DMap k Identity)) -- The currently-firing occurrence of this event
1023 , rootSubscribed :: !(IORef (DMap k (RootSubscribed x)))
1022 , rootSubscribed :: !(IORef (DMap k (RootSubscribed x)))
1024 , rootInit :: !(forall a. k a -> RootTrigger x a -> IO (IO ()))
1023 , rootInit :: !(forall a. k a -> RootTrigger x a -> IO (IO ()))
@@ -1088,25 +1087,25 @@ heightBagVerify b@(HeightBag s c) = if
1088heightBagVerify = id
1087heightBagVerify = id
1089#endif
1088#endif
1090
1089
1091−data FanSubscribedChildren x k v a = FanSubscribedChildren
1090+data FanSubscribedChildren (x :: *) k a = FanSubscribedChildren
1092− { _fanSubscribedChildren_list :: !(WeakBag (Subscriber x (v a)))
1091+ { _fanSubscribedChildren_list :: !(WeakBag (Subscriber x a))
1093− , _fanSubscribedChildren_self :: {-# NOUNPACK #-} !(k a, FanSubscribed x k v)
1092+ , _fanSubscribedChildren_self :: {-# NOUNPACK #-} !(k a, FanSubscribed x k)
1094− , _fanSubscribedChildren_weakSelf :: !(IORef (Weak (k a, FanSubscribed x k v)))
1093+ , _fanSubscribedChildren_weakSelf :: !(IORef (Weak (k a, FanSubscribed x k)))
1095 }
1094 }
1096
1095
1097−data FanSubscribed x k v
1096+data FanSubscribed (x :: *) k
1098− = FanSubscribed { fanSubscribedCachedSubscribed :: !(IORef (Maybe (FanSubscribed x k v)))
1097+ = FanSubscribed { fanSubscribedCachedSubscribed :: !(IORef (Maybe (FanSubscribed x k)))
1099− , fanSubscribedOccurrence :: !(IORef (Maybe (DMap k v)))
1098+ , fanSubscribedOccurrence :: !(IORef (Maybe (DMap k Identity)))
1100− , fanSubscribedSubscribers :: !(IORef (DMap k (FanSubscribedChildren x k v))) -- This DMap should never be empty
1099+ , fanSubscribedSubscribers :: !(IORef (DMap k (FanSubscribedChildren x k))) -- This DMap should never be empty
1101 , fanSubscribedParent :: !(EventSubscription x)
1100 , fanSubscribedParent :: !(EventSubscription x)
1102#ifdef DEBUG_NODEIDS
1101#ifdef DEBUG_NODEIDS
1103 , fanSubscribedNodeId :: Int
1102 , fanSubscribedNodeId :: Int
1104#endif
1103#endif
1105 }
1104 }
1106
1105
1107−data Fan x k v
1106+data Fan x k
1108− = Fan { fanParent :: !(Event x (DMap k v))
1107+ = Fan { fanParent :: !(Event x (DMap k Identity))
1109− , fanSubscribed :: !(IORef (Maybe (FanSubscribed x k v)))
1108+ , fanSubscribed :: !(IORef (Maybe (FanSubscribed x k)))
1110 }
1109 }
1111
1110
1112data SwitchSubscribed x a
1111data SwitchSubscribed x a
@@ -1560,7 +1559,7 @@ fanInt p =
1560 return (EventSubscription (FastWeakBag.remove t) $! EventSubscribed heightRef $! toAny (_fanInt_subscriptionRef self, t), IntMap.lookup k currentOcc)
1559 return (EventSubscription (FastWeakBag.remove t) $! EventSubscribed heightRef $! toAny (_fanInt_subscriptionRef self, t), IntMap.lookup k currentOcc)
1561
1560
1562{-# INLINABLE getFanSubscribed #-}
1561{-# INLINABLE getFanSubscribed #-}
1563−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))
1562+getFanSubscribed :: (HasSpiderTimeline x, GCompare k) => k a -> Fan x k -> Subscriber x a -> EventM x (WeakBagTicket, FanSubscribed x k, Maybe a)
1564getFanSubscribed k f sub = do
1563getFanSubscribed k f sub = do
1565 mSubscribed <- liftIO $ readIORef $ fanSubscribed f
1564 mSubscribed <- liftIO $ readIORef $ fanSubscribed f
1566 case mSubscribed of
1565 case mSubscribed of
@@ -1594,7 +1593,7 @@ getFanSubscribed k f sub = do
1594 liftIO $ writeIORef (fanSubscribed f) $ Just subscribed
1593 liftIO $ writeIORef (fanSubscribed f) $ Just subscribed
1595 return (slnForSub, subscribed, coerce $ DMap.lookup k =<< parentOcc)
1594 return (slnForSub, subscribed, coerce $ DMap.lookup k =<< parentOcc)
1596
1595
1597−cleanupFanSubscribed :: GCompare k => (k a, FanSubscribed x k v) -> IO ()
1596+cleanupFanSubscribed :: GCompare k => (k a, FanSubscribed x k) -> IO ()
1598cleanupFanSubscribed (k, subscribed) = do
1597cleanupFanSubscribed (k, subscribed) = do
1599 subscribers <- readIORef $ fanSubscribedSubscribers subscribed
1598 subscribers <- readIORef $ fanSubscribedSubscribers subscribed
1600 let reducedSubscribers = DMap.delete k subscribers
1599 let reducedSubscribers = DMap.delete k subscribers
@@ -1606,7 +1605,7 @@ cleanupFanSubscribed (k, subscribed) = do
1606 else writeIORef (fanSubscribedSubscribers subscribed) $! reducedSubscribers
1605 else writeIORef (fanSubscribedSubscribers subscribed) $! reducedSubscribers
1607
1606
1608{-# INLINE subscribeFanSubscribed #-}
1607{-# INLINE subscribeFanSubscribed #-}
1609−subscribeFanSubscribed :: GCompare k => k a -> FanSubscribed x k v -> Subscriber x (v a) -> IO WeakBagTicket
1608+subscribeFanSubscribed :: GCompare k => k a -> FanSubscribed x k -> Subscriber x a -> IO WeakBagTicket
1610subscribeFanSubscribed k subscribed sub = do
1609subscribeFanSubscribed k subscribed sub = do
1611 subscribers <- readIORef $ fanSubscribedSubscribers subscribed
1610 subscribers <- readIORef $ fanSubscribedSubscribers subscribed
1612 case DMap.lookup k subscribers of
1611 case DMap.lookup k subscribers of
@@ -2082,15 +2081,14 @@ mergeIntCheap d = Event $ \sub -> do
2082 )
2081 )
2083
2082
2084newtype EventSelector x k = EventSelector { select :: forall a. k a -> Event x a }
2083newtype EventSelector x k = EventSelector { select :: forall a. k a -> Event x a }
2085−newtype EventSelectorG x k v = EventSelectorG { selectG :: forall a. k a -> Event x (v a) }
2086
2084
2087−fanG :: (HasSpiderTimeline x, GCompare k) => Event x (DMap k v) -> EventSelectorG x k v
2085+fan :: (HasSpiderTimeline x, GCompare k) => Event x (DMap k Identity) -> EventSelector x k
2088−fanG e =
2086+fan e =
2089 let f = Fan
2087 let f = Fan
2090 { fanParent = e
2088 { fanParent = e
2091 , fanSubscribed = unsafeNewIORef e Nothing
2089 , fanSubscribed = unsafeNewIORef e Nothing
2092 }
2090 }
2093− in EventSelectorG $ \k -> eventFan k f
2091+ in EventSelector $ \k -> eventFan k f
2094
2092
2095runHoldInits :: HasSpiderTimeline x => IORef [SomeHoldInit x] -> IORef [SomeDynInit x] -> IORef [SomeMergeInit x] -> EventM x ()
2093runHoldInits :: HasSpiderTimeline x => IORef [SomeHoldInit x] -> IORef [SomeDynInit x] -> IORef [SomeMergeInit x] -> EventM x ()
2096runHoldInits holdInitRef dynInitRef mergeInitRef = do
2094runHoldInits holdInitRef dynInitRef mergeInitRef = do
@@ -2559,8 +2557,6 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2559 pushCheap f = SpiderEvent . pushCheap (coerce f) . unSpiderEvent
2557 pushCheap f = SpiderEvent . pushCheap (coerce f) . unSpiderEvent
2560 {-# INLINABLE pull #-}
2558 {-# INLINABLE pull #-}
2561 pull = SpiderBehavior . pull . coerce
2559 pull = SpiderBehavior . pull . coerce
2562− {-# INLINABLE fanG #-}
2563− fanG e = R.EventSelectorG $ SpiderEvent . selectG (fanG (unSpiderEvent e))
2564 {-# INLINABLE mergeG #-}
2560 {-# INLINABLE mergeG #-}
2565 mergeG
2561 mergeG
2566 :: forall (k :: k2 -> *) q (v :: k2 -> *). GCompare k
2562 :: forall (k :: k2 -> *) q (v :: k2 -> *). GCompare k
@@ -2568,6 +2564,8 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2568 -> DMap k q
2564 -> DMap k q
2569 -> R.Event (SpiderTimeline x) (DMap k v)
2565 -> R.Event (SpiderTimeline x) (DMap k v)
2570 mergeG nt = SpiderEvent . mergeG (unSpiderEvent #. nt) . dynamicConst
2566 mergeG nt = SpiderEvent . mergeG (unSpiderEvent #. nt) . dynamicConst
2567+ {-# INLINABLE fan #-}
2568+ fan e = R.EventSelector $ SpiderEvent . select (fan (unSpiderEvent e))
2571 {-# INLINABLE switch #-}
2569 {-# INLINABLE switch #-}
2572 switch = SpiderEvent . switch . (coerce :: Behavior x (R.Event (SpiderTimeline x) a) -> Behavior x (Event x a)) . unSpiderBehavior
2570 switch = SpiderEvent . switch . (coerce :: Behavior x (R.Event (SpiderTimeline x) a) -> Behavior x (Event x a)) . unSpiderBehavior
2573 {-# INLINABLE coincidence #-}
2571 {-# INLINABLE coincidence #-}
test/GC.hs+2−2
@@ -56,8 +56,8 @@ hostPerf ref = S.runSpiderHost $ do
56 { S.subscriberPropagate = S.subscriberPropagate sub
56 { S.subscriberPropagate = S.subscriberPropagate sub
57 }
57 }
58 return (s, o))
58 return (s, o))
59− $ runIdentity . runIdentity <$> S.selectG
59+ $ runIdentity <$> S.select
60− (S.fanG $ S.pushCheap (return . Just . mapKeyValuePairsMonotonic (\(t :=> e) -> WrapArg t :=> Identity e)) response)
60+ (S.fan $ S.pushCheap (return . Just . mapKeyValuePairsMonotonic (\(t :=> e) -> WrapArg t :=> Identity e)) response)
61 (WrapArg Request)
61 (WrapArg Request)
62 return $ alignWith (mergeThese (<>))
62 return $ alignWith (mergeThese (<>))
63 (flip S.pushCheap eadd $ \_ -> return $ Just $ DMap.singleton Request $ do
63 (flip S.pushCheap eadd $ \_ -> return $ Just $ DMap.singleton Request $ do