on master help sign in
implement foldr/build fusion for unfoldr/foldrM
commitf0c11b549093b64746fe7164000f86a7ec993ce3 authorHarendra Kumar <harendra.kumar@gmail.com> dateThu 29 Aug 2019, 18:27 (7 years ago) parenta014617
2 files changed+31−6
src/Streamly/Streams/StreamK.hs+6−6 src/Streamly/Streams/StreamK/Type.hs+25
src/Streamly/Streams/StreamK.hs+6−6
@@ -215,12 +215,12 @@ uncons m =
215215
216216{-# INLINE unfoldr #-}
217217unfoldr :: IsStream t => (b -> Maybe (a, b)) -> b -> t m a
218−unfoldr step = go
219− where
220− go s = buildS $ \yld stp ->
221− case step s of
222− Just (a, b) -> yld a (go b)
223− Nothing -> stp
218+unfoldr next s0 = build $ \yld stp ->
219+ let go s =
220+ case next s of
221+ Just (a, b) -> yld a (go b)
222+ Nothing -> stp
223+ in go s0
224224
225225{-# INLINE unfoldrM #-}
226226unfoldrM :: (IsStream t, MonadAsync m) => (b -> m (Maybe (a, b))) -> b -> t m a
src/Streamly/Streams/StreamK/Type.hs+25
@@ -50,6 +50,7 @@ module Streamly.Streams.StreamK.Type
5050 , foldrM
5151 , foldrS
5252 , foldrSM
53+ , build
5354 , buildS
5455 , buildM
5556 , buildSM
@@ -550,6 +551,30 @@ foldrSMShared = foldrSMWith foldStreamShared
550551-- build
551552-------------------------------------------------------------------------------
552553
554+{-# INLINE_NORMAL build #-}
555+build :: IsStream t => forall a. (forall b. (a -> b -> b) -> b -> b) -> t m a
556+build g = g cons nil
557+
558+{-# RULES "foldrM/build"
559+ forall k z (g :: forall b. (a -> b -> b) -> b -> b).
560+ foldrM k z (build g) = g k z #-}
561+
562+{-# RULES "foldrS/build"
563+ forall k z (g :: forall b. (a -> b -> b) -> b -> b).
564+ foldrS k z (build g) = g k z #-}
565+
566+{-# RULES "foldrS/cons/build"
567+ forall k z x (g :: forall b. (a -> b -> b) -> b -> b).
568+ foldrS k z (x `cons` build g) = k x (g k z) #-}
569+
570+{-# RULES "foldrSShared/build"
571+ forall k z (g :: forall b. (a -> b -> b) -> b -> b).
572+ foldrSShared k z (build g) = g k z #-}
573+
574+{-# RULES "foldrSShared/cons/build"
575+ forall k z x (g :: forall b. (a -> b -> b) -> b -> b).
576+ foldrSShared k z (x `cons` build g) = k x (g k z) #-}
577+
553578-- build a stream by applying cons and nil to a build function
554579{-# INLINE_NORMAL buildS #-}
555580buildS :: IsStream t => ((a -> t m a -> t m a) -> t m a -> t m a) -> t m a