@@ -685,19 +685,57 @@ longest :: -- Monad m =>
685685 Fold m x a -> Fold m x a -> Fold m x a
686686longest _f1 _f2 = undefined
687687
688+data ConcatMapState m sa a c
689+ = B !sa
690+ | forall s. C (s -> a -> m (Step s c)) !s (s -> m c)
691+
688692-- | Map a 'Fold' returning function on the result of a 'Fold'.
689693--
690−-- Compare with 'Monad' instance method '>>='. This implementation allows
691−-- stream fusion but has quadratic complexity. This can fuse with other
692−-- operations and can be much faster than 'Monad' instance for small number
693−-- (less than 8) of compositions.
694+-- Compare with 'Monad' instance method '>>='.
694695--
695−-- /Unimplemented/
696+-- >>> Stream.fold (concatMap (flip Fold.takeLE Fold.sum) (Fold.rmapM (return . fromJust) Fold.head)) $ Stream.fromList [10,9..1]
697+-- 45
698+--
699+-- /Internal/
696700--
697701{-# INLINE concatMap #-}
698−concatMap :: -- Monad m =>
699− (b -> Fold m a c) -> Fold m a b -> Fold m a c
700−concatMap _func _fld = undefined
702+concatMap :: Monad m => (b -> Fold m a c) -> Fold m a b -> Fold m a c
703+concatMap f (Fold stepa initiala extracta) = Fold stepc initialc extractc
704+ where
705+ initialc = do
706+ r <- initiala
707+ case r of
708+ Partial s -> return $ Partial (B s)
709+ Done b -> initInnerFold (f b)
710+
711+ stepc (B s) a = do
712+ r <- stepa s a
713+ case r of
714+ Partial s1 -> return $ Partial (B s1)
715+ Done b -> initInnerFold (f b)
716+
717+ stepc (C stepInner s extractInner) a = do
718+ r <- stepInner s a
719+ return $ case r of
720+ Partial sc -> Partial (C stepInner sc extractInner)
721+ Done c -> Done c
722+
723+ extractc (B s) = do
724+ r <- extracta s
725+ initExtract (f r)
726+ extractc (C _ sInner extractInner) = extractInner sInner
727+
728+ initInnerFold (Fold step i e) = do
729+ r <- i
730+ return $ case r of
731+ Partial s -> Partial (C step s e)
732+ Done c -> Done c
733+
734+ initExtract (Fold _ i e) = do
735+ r <- i
736+ case r of
737+ Partial s -> e s
738+ Done c -> return c
701739
702740-- | Combines the outputs of the folds (the type @b@) using their 'Semigroup'
703741-- instances.