@@ -169,6 +169,7 @@ module Reflex.Class
169169 , tagCheap
170170 , mergeWithCheap
171171 , mergeWithCheap'
172+ , sconcatCheap
172173 -- * Slow, but general, implementations
173174 , slowHeadE
174175 ) where
@@ -890,6 +891,9 @@ instance (Semigroup a, Reflex t) => Semigroup (Event t a) where
890891 sconcat = fmap sconcat . mergeList . toList
891892 stimes n = fmap $ stimes n
892893
894+sconcatCheap :: (Semigroup a, Reflex t) => NonEmpty (Event t a) -> Event t a
895+sconcatCheap = fmapCheap sconcat . mergeList . toList
896+
893897instance (Semigroup a, Reflex t) => Monoid (Event t a) where
894898 mempty = never
895899 mappend = (<>)
@@ -904,6 +908,8 @@ mergeWith = mergeWith' id
904908
905909{-# INLINE mergeWith' #-}
906910mergeWith' :: Reflex t => (a -> b) -> (b -> b -> b) -> [Event t a] -> Event t b
911+mergeWith' _ _ [] = never
912+mergeWith' f _ [e] = fmap f e
907913mergeWith' f g es = fmap (Prelude.foldl1 g . fmap f)
908914 . mergeInt
909915 . IntMap.fromDistinctAscList
@@ -921,6 +927,7 @@ leftmost = mergeWith const
921927-- time.
922928mergeList :: Reflex t => [Event t a] -> Event t (NonEmpty a)
923929mergeList [] = never
930+mergeList [e] = fmapCheap (:|[]) e
924931mergeList es = mergeWithFoldCheap' id es
925932
926933unsafeMapIncremental
@@ -1017,7 +1024,11 @@ switchHoldPromptly ea0 eea = do
10171024switchHoldPromptOnly :: (Reflex t, MonadHold t m) => Event t a -> Event t (Event t a) -> m (Event t a)
10181025switchHoldPromptOnly e0 e' = do
10191026 eLag <- switch <$> hold e0 e'
1020− return $ coincidence $ leftmost [e', eLag <$ eLag]
1027+ return $ fmapMaybeCheap id $ leftmost
1028+ [ fmapCheap Just $ coincidence e'
1029+ , fmapCheap (const Nothing) e'
1030+ , fmapCheap Just eLag
1031+ ]
10211032
10221033-- | When the given outer event fires, condense the inner events into the contained patch. Non-firing inner events will be replaced with deletions.
10231034coincidencePatchMap :: (Reflex t, Ord k) => Event t (PatchMap k (Event t v)) -> Event t (PatchMap k v)
@@ -1649,6 +1660,8 @@ mergeWithCheap' f g = mergeWithFoldCheap' $ foldl1 g . fmap f
16491660-- | A "cheap" version of 'mergeWithFoldCheap''. See the performance note on 'pushCheap'.
16501661{-# INLINE mergeWithFoldCheap' #-}
16511662mergeWithFoldCheap' :: Reflex t => (NonEmpty a -> b) -> [Event t a] -> Event t b
1663+mergeWithFoldCheap' f [] = never
1664+mergeWithFoldCheap' f [e] = fmapCheap (f . (:|[])) e
16521665mergeWithFoldCheap' f es =
16531666 fmapCheap (f . (\(h : t) -> h :| t) . IntMap.elems)
16541667 . mergeInt