@@ -90,6 +90,11 @@ module Streamly.Streams.StreamD
9090 , find
9191 , (!!)
9292
93+ -- ** Substreams
94+ , isPrefixOf
95+ , isSubsequenceOf
96+ , stripPrefix
97+
9398 -- ** Map and Fold
9499 , mapM_
95100
@@ -580,6 +585,73 @@ findIndices p (Stream step state) = Stream step' (state, 0)
580585 Skip s -> Skip (s, i+1)
581586 Stop -> Stop
582587
588+------------------------------------------------------------------------------
589+-- Substreams
590+------------------------------------------------------------------------------
591+
592+{-# INLINE_NORMAL isPrefixOf #-}
593+isPrefixOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
594+isPrefixOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
595+ where
596+ go (sa, sb, Nothing) = do
597+ r <- stepa defState sa
598+ case r of
599+ Yield x sa' -> go (sa', sb, Just x)
600+ Skip sa' -> go (sa', sb, Nothing)
601+ Stop -> return True
602+
603+ go (sa, sb, Just x) = do
604+ r <- stepb defState sb
605+ case r of
606+ Yield y sb' ->
607+ if x == y
608+ then go (sa, sb', Nothing)
609+ else return False
610+ Skip sb' -> go (sa, sb', Just x)
611+ Stop -> return False
612+
613+{-# INLINE_NORMAL isSubsequenceOf #-}
614+isSubsequenceOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
615+isSubsequenceOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
616+ where
617+ go (sa, sb, Nothing) = do
618+ r <- stepa defState sa
619+ case r of
620+ Yield x sa' -> go (sa', sb, Just x)
621+ Skip sa' -> go (sa', sb, Nothing)
622+ Stop -> return True
623+
624+ go (sa, sb, Just x) = do
625+ r <- stepb defState sb
626+ case r of
627+ Yield y sb' ->
628+ if x == y
629+ then go (sa, sb', Nothing)
630+ else go (sa, sb', Just x)
631+ Skip sb' -> go (sa, sb', Just x)
632+ Stop -> return False
633+
634+{-# INLINE_NORMAL stripPrefix #-}
635+stripPrefix :: (Eq a, Monad m) => Stream m a -> Stream m a -> m (Maybe (Stream m a))
636+stripPrefix (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
637+ where
638+ go (sa, sb, Nothing) = do
639+ r <- stepa defState sa
640+ case r of
641+ Yield x sa' -> go (sa', sb, Just x)
642+ Skip sa' -> go (sa', sb, Nothing)
643+ Stop -> return $ Just (Stream stepb sb)
644+
645+ go (sa, sb, Just x) = do
646+ r <- stepb defState sb
647+ case r of
648+ Yield y sb' ->
649+ if x == y
650+ then go (sa, sb', Nothing)
651+ else return Nothing
652+ Skip sb' -> go (sa, sb', Just x)
653+ Stop -> return Nothing
654+
583655------------------------------------------------------------------------------
584656-- Map and Fold
585657------------------------------------------------------------------------------