@@ -142,6 +142,7 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
142142 -- | Opposite to compact in ArrayStream
143143 , splitInnerBy
144144 , splitInnerBySuffix
145+ , intersectBySorted
145146 )
146147where
147148
@@ -482,6 +483,59 @@ mergeBy
482483 => (a -> a -> Ordering ) -> Stream m a -> Stream m a -> Stream m a
483484mergeBy cmp = mergeByM (\ a b -> return $ cmp a b)
484485
486+ -------------------------------------------------------------------------------
487+ -- Intersection of sorted streams ---------------------------------------------
488+ -------------------------------------------------------------------------------
489+ {-# INLINE_NORMAL intersectBySorted #-}
490+ intersectBySorted
491+ :: (MonadIO m , Eq a )
492+ => (a -> a -> Ordering ) -> Stream m a -> Stream m a -> Stream m a
493+ intersectBySorted cmp (Stream stepa ta) (Stream stepb tb) =
494+ Stream step (Just ta, Just tb, Nothing , Nothing , Nothing )
495+
496+ where
497+ {-# INLINE_LATE step #-}
498+
499+ -- step 1
500+ step gst (Just sa, sb, Nothing , b, Nothing ) = do
501+ r <- stepa gst sa
502+ return $ case r of
503+ Yield a sa' -> Skip (Just sa', sb, Just a, b, Nothing )
504+ Skip sa' -> Skip (Just sa', sb, Nothing , b, Nothing )
505+ Stop -> Stop
506+
507+ -- step 2
508+ step gst (sa, Just sb, a, Nothing , Nothing ) = do
509+ r <- stepb gst sb
510+ return $ case r of
511+ Yield b sb' -> Skip (sa, Just sb', a, Just b, Nothing )
512+ Skip sb' -> Skip (sa, Just sb', a, Nothing , Nothing )
513+ Stop -> Stop
514+
515+ -- step 3
516+ -- both the values are available compare it
517+ step _ (sa, sb, Just a, Just b, Nothing ) = do
518+ let res = cmp a b
519+ return $ case res of
520+ GT -> Skip (sa, sb, Just a, Nothing , Nothing )
521+ LT -> Skip (sa, sb, Nothing , Just b, Nothing )
522+ EQ -> Yield a (sa, sb, Nothing , Just a, Just b) -- step 4
523+
524+ -- step 4
525+ -- Matching element
526+ step gst (Just sa, Just sb, Nothing , Just _, Just b) = do
527+ r1 <- stepa gst sa
528+ return $ case r1 of
529+ Yield a' sa' -> do
530+ if a' == b -- match with prev a
531+ then Yield a' (Just sa', Just sb, Nothing , Just b, Just b) -- step 1
532+ else Skip (Just sa', Just sb, Just a', Nothing , Nothing )
533+
534+ Skip sa' -> Skip (Just sa', Just sb, Nothing , Nothing , Nothing )
535+ Stop -> Stop
536+
537+ step _ (_, _, _, _, _) = return Stop
538+
485539------------------------------------------------------------------------------
486540-- Combine N Streams - unfoldMany
487541------------------------------------------------------------------------------
0 commit comments