@@ -236,6 +236,7 @@ module Streamly.Internal.Data.Fold.Type
236236
237237 -- ** Parallel Distribution
238238 , GenericRunner(..)
239+ , FstRunner(..)
239240 , teeWith
240241 , teeWithFst
241242 , teeWithMin
@@ -708,12 +709,44 @@ serialWith func (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
708709-- | Same as applicative '*>'. Run two folds serially one after the other
709710-- discarding the result of the first.
710711--
711−-- /Unimplemented/
712−--
713712{-# INLINE serial_ #-}
714−serial_ :: -- Monad m =>
713+serial_ :: Monad m =>
715714 Fold m x a -> Fold m x b -> Fold m x b
716−serial_ _f1 _f2 = undefined
715+serial_ (Fold stepL initialL _) (Fold stepR initialR extractR) =
716+ Fold step initial extract
717+
718+ where
719+
720+ func _ b = b
721+
722+ initial = do
723+ resL <- initialL
724+ case resL of
725+ Partial sl -> return $ Partial $ SeqFoldL sl
726+ Done bl -> do
727+ resR <- initialR
728+ return $ first (SeqFoldR (func bl)) resR
729+
730+ step (SeqFoldL st) a = do
731+ r <- stepL st a
732+ case r of
733+ Partial s -> return $ Partial (SeqFoldL s)
734+ Done b -> do
735+ res <- initialR
736+ return $ first (SeqFoldR (func b)) res
737+ step (SeqFoldR f st) a = do
738+ r <- stepR st a
739+ return $
740+ case r of
741+ Partial s -> Partial (SeqFoldR f s)
742+ Done b -> Done b
743+
744+ extract (SeqFoldR _ sR) = extractR sR
745+ extract (SeqFoldL _) = do
746+ res <- initialR
747+ case res of
748+ Partial sR -> extractR sR
749+ Done rR -> return rR
717750
718751{-# ANN type GenericRunner Fuse #-}
719752data GenericRunner sL sR bL bR
@@ -721,6 +754,11 @@ data GenericRunner sL sR bL bR
721754 | RunLeft !sL !bR
722755 | RunRight !bL !sR
723756
757+{-# ANN type FstRunner Fuse #-}
758+data FstRunner sL sR b
759+ = RunFstBoth !sL !sR
760+ | RunFstLeft !sL !b
761+
724762-- | @teeWith k f1 f2@ distributes its input to both @f1@ and @f2@ until both
725763-- of them terminate and combines their output using @k@.
726764--
@@ -797,42 +835,223 @@ teeWith f (Fold stepL beginL doneL) (Fold stepR beginR doneR) =
797835
798836-- | Like 'teeWith' but terminates as soon as the first fold terminates.
799837--
800−-- /Unimplemented/
838+-- /Pre-release/
801839--
802840{-# INLINE teeWithFst #-}
803−teeWithFst :: (b -> c -> d) -> Fold m a b -> Fold m a c -> Fold m a d
804−teeWithFst = undefined
841+teeWithFst :: Monad m => (b -> c -> d) -> Fold m a b -> Fold m a c -> Fold m a d
842+teeWithFst f (Fold stepL beginL doneL) (Fold stepR beginR doneR) =
843+ Fold step begin done
844+
845+ where
846+
847+ begin = do
848+ resL <- beginL
849+ resR <- beginR
850+
851+ case resL of
852+ Partial sl ->
853+ return $ Partial $
854+ case resR of
855+ Partial sr -> RunFstBoth sl sr
856+ Done br -> RunFstLeft sl br
857+ Done bl -> do
858+ case resR of
859+ Partial sr -> do
860+ br <- doneR sr
861+ return $ Done $ f bl br
862+ Done br -> return $ Done $ f bl br
863+
864+ step (RunFstBoth sL sR) a = do
865+ resL <- stepL sL a
866+ resR <- stepR sR a
867+ case resL of
868+ Partial sL1 ->
869+ return
870+ $ Partial
871+ $ case resR of
872+ Partial sR1 -> RunFstBoth sL1 sR1
873+ Done bR -> RunFstLeft sL1 bR
874+ Done bL ->
875+ case resR of
876+ Partial sR1 -> do
877+ br <- doneR sR1
878+ return $ Done $ f bL br
879+ Done bR -> return $ Done $ f bL bR
880+
881+ step (RunFstLeft sL bR) a = do
882+ resL <- stepL sL a
883+ return
884+ $ case resL of
885+ Partial sL1 -> Partial $ RunFstLeft sL1 bR
886+ Done bL -> Done $ f bL bR
887+
888+ done (RunFstBoth sL sR) = do
889+ bL <- doneL sL
890+ bR <- doneR sR
891+ return $ f bL bR
892+ done (RunFstLeft sL bR) = do
893+ bL <- doneL sL
894+ return $ f bL bR
805895
806896-- | Like 'teeWith' but terminates as soon as any one of the two folds
807897-- terminates.
808898--
809−-- /Unimplemented/
899+-- /Pre-release/
810900--
811901{-# INLINE teeWithMin #-}
812−teeWithMin :: (b -> c -> d) -> Fold m a b -> Fold m a c -> Fold m a d
813−teeWithMin = undefined
902+teeWithMin :: Monad m => (b -> c -> d) -> Fold m a b -> Fold m a c -> Fold m a d
903+teeWithMin f (Fold stepL beginL doneL) (Fold stepR beginR doneR) =
904+ Fold step begin done
905+
906+ where
907+
908+ begin = do
909+ resL <- beginL
910+ resR <- beginR
911+ case resL of
912+ Partial sL1 -> do
913+ case resR of
914+ Partial sR1 -> return $ Partial $ Tuple' sL1 sR1
915+ Done br -> do
916+ bl <- doneL sL1
917+ return $ Done $ f bl br
918+
919+ Done bl -> do
920+ case resR of
921+ Partial sr -> do
922+ br <- doneR sr
923+ return $ Done $ f bl br
924+ Done br -> return $ Done $ f bl br
925+
926+ step (Tuple' sL sR) a = do
927+ resL <- stepL sL a
928+ resR <- stepR sR a
929+ case resL of
930+ Partial sL1 ->
931+ case resR of
932+ Partial sR1 -> return $ Partial $ Tuple' sL1 sR1
933+ Done bR -> do
934+ bL <- doneL sL1
935+ return $ Done $ f bL bR
936+ Done bL ->
937+ case resR of
938+ Partial sR1 -> do
939+ br <- doneR sR1
940+ return $ Done $ f bL br
941+ Done bR -> return $ Done $ f bL bR
942+
943+ done (Tuple' sL sR) = do
944+ bL <- doneL sL
945+ bR <- doneR sR
946+ return $ f bL bR
814947
815948-- | Shortest alternative. Apply both folds in parallel but choose the result
816949-- from the one which consumed least input i.e. take the shortest succeeding
817950-- fold.
818951--
819−-- /Unimplemented/
952+-- /Pre-release/
820953--
821954{-# INLINE shortest #-}
822−shortest :: -- Monad m =>
823− Fold m x a -> Fold m x a -> Fold m x a
824−shortest _f1 _f2 = undefined
955+shortest :: Monad m => Fold m x a -> Fold m x b -> Fold m x (Either a b)
956+shortest (Fold stepL beginL doneL) (Fold stepR beginR _) =
957+ Fold step begin done
958+
959+ where
960+
961+ begin = do
962+ resL <- beginL
963+ resR <- beginR
964+ return $
965+ case resL of
966+ Partial sL ->
967+ case resR of
968+ Partial sR -> Partial $ Tuple' sL sR
969+ Done bR -> Done $ Right bR
970+ Done bL -> Done $ Left bL
971+
972+ step (Tuple' sL sR) a = do
973+ resL <- stepL sL a
974+ resR <- stepR sR a
975+ return $
976+ case resL of
977+ Partial sL1 ->
978+ case resR of
979+ Partial sR1 -> Partial $ Tuple' sL1 sR1
980+ Done bR -> Done $ Right bR
981+ Done bL -> Done $ Left bL
982+
983+ done (Tuple' sL _) = do
984+ x <- doneL sL
985+ return $ Left x
986+
987+{-# ANN type LongestRunner Fuse #-}
988+data LongestRunner sL sR bL bR
989+ = LongestRunBoth !sL !sR
990+ | LongestRunLeft !sL !bR
991+ | LongestRunRight !bL !sR
825992
826993-- | Longest alternative. Apply both folds in parallel but choose the result
827994-- from the one which consumed more input i.e. take the longest succeeding
828995-- fold.
829996--
830−-- /Unimplemented/
997+-- /Pre-release/
831998--
832−{-# INLINE longest #-}
833−longest :: -- Monad m =>
834− Fold m x a -> Fold m x a -> Fold m x a
835−longest _f1 _f2 = undefined
999+longest :: Monad m => Fold m x a -> Fold m x b -> Fold m x (Either a b)
1000+longest (Fold stepL beginL doneL) (Fold stepR beginR doneR) =
1001+ Fold step begin done
1002+
1003+ where
1004+
1005+ begin = do
1006+ resL <- beginL
1007+ resR <- beginR
1008+ return $
1009+ case resL of
1010+ Partial sL ->
1011+ Partial $
1012+ case resR of
1013+ Partial sR -> LongestRunBoth sL sR
1014+ Done bR -> LongestRunLeft sL bR
1015+ Done bL ->
1016+ case resR of
1017+ Partial sR -> Partial $ LongestRunRight bL sR
1018+ Done bR -> Done $ Right bR
1019+
1020+ step (LongestRunBoth sL sR) a = do
1021+ resL <- stepL sL a
1022+ resR <- stepR sR a
1023+ case resL of
1024+ Partial sL1 ->
1025+ return
1026+ $ Partial
1027+ $ case resR of
1028+ Partial sR1 -> LongestRunBoth sL1 sR1
1029+ Done bR -> LongestRunLeft sL1 bR
1030+ Done bL ->
1031+ return
1032+ $ case resR of
1033+ Partial sR1 -> Partial $ LongestRunRight bL sR1
1034+ Done bR -> Done $ Right bR
1035+
1036+ step (LongestRunLeft sL bR) a = do
1037+ resL <- stepL sL a
1038+ return $
1039+ case resL of
1040+ Partial sL1 -> Partial $ LongestRunLeft sL1 bR
1041+ Done bL -> Done $ Left bL
1042+
1043+ step (LongestRunRight bL sR) a = do
1044+ resR <- stepR sR a
1045+ return
1046+ $ case resR of
1047+ Partial sR1 -> Partial $ LongestRunRight bL sR1
1048+ Done bR -> Done $ Right bR
1049+
1050+ done (LongestRunLeft sL _) = Left <$> doneL sL
1051+
1052+ done (LongestRunRight _ sR) = Right <$> doneR sR
1053+
1054+ done (LongestRunBoth sL _) = Left <$> doneL sL
8361055
8371056data ConcatMapState m sa a c
8381057 = B !sa