I meant to agree that the pipes-group method was the true path, but I think you can always produce this sort of effect if you make something like the io-stream rule explicit, it's just a little tiresome. My impression was that there was no way to support it systematically without making a mess of everything, but see e.g.
import Pipes import qualified Pipes.Prelude as P import Pipes.Group import Lens.Simple import Control.Monad foldValues :: (Monad m, Eq k) => (v -> v -> v) -> Producer (k, v) m r -> Producer (k, v) m r foldValues append xs = P.concat <-< folds step Nothing id (view (groupsBy keyEq) xs) where keyEq (k, _) (k', _) = k == k' step (Nothing) (k, v) = Just (k, v) step (Just (_, v0)) (k, v) = Just (k, v0 `append` v) pipeFoldValues :: (Monad m, Eq k) => (v -> v -> v) -> Pipe (k,v) (k, v) m r pipeFoldValues append = go Nothing where go (Just (k,v)) = do a <- await case a of (k',v') | k == k' -> go (Just (k,append v v')) (k',v') -> do yield (k,v) go (Just (k',v')) go Nothing = do a <- await go (Just a) pipeFoldValues' :: (Monad m, Eq k) => (v -> v -> v) -> Pipe (Maybe (k,v)) (Maybe (k, v)) m r pipeFoldValues' append = go Nothing where go (Just (k,v)) = do a <- await case a of Nothing -> yield (Just (k,v)) >> forever (yield Nothing) Just (k',v') | k == k' -> go (Just (k,append v v')) Just (k',v') -> do yield (Just (k,v)) go (Just (k',v')) go Nothing = do a <- await go a pipeFoldValues'' :: (Monad m, Eq k) => (v -> v -> v) -> Pipe (Either r (k,v)) (Either r (k, v)) m x pipeFoldValues'' append = go Nothing where go (Just (k,v)) = do e <- await case e of Left r -> yield (Right (k,v)) >> forever (yield (Left r)) Right (k',v') | k == k' -> go (Just (k,append v v')) Right (k',v') -> do yield (Right (k,v)) go (Just (k',v')) go Nothing = do a <- await case a of Left r -> forever (yield (Left r)) Right (k,v) -> go (Just (k,v)) -- dubious kit for Nothing or Left ending streams: eof p = do p >-> P.map Just forever $ yield Nothing uneof = do n <- await case n of Nothing -> return () Just a -> yield a >> uneof internalize p = do r <- p >-> P.map Right forever $ yield (Left r) externalize = do e <- await case e of Left r -> return r Right a -> yield a >> externalize -- demo -- q = each (zip ["hi","hi","ho","ho","hi","hi"] (repeat 2)) run p = runEffect $ p >-> P.print p1 = foldValues (+) q p2 = q >-> pipeFoldValues (+) p3 = eof q >-> pipeFoldValues' (+) >-> uneof p4 = internalize q >-> pipeFoldValues'' (+) >-> externalize p4' = internalize (q >> return "hi") >-> (P.tee P.print) >-> pipeFoldValues'' (+) >-> externalize -- [*Main] -- > run p1 -- ("hi",4) -- ("ho",4) -- ("hi",4) -- [*Main] -- > run p2 -- ("hi",4) -- ("ho",4) -- <- missing last group -- [*Main] -- > run p3 -- ("hi",4) -- ("ho",4) -- ("hi",4) -- [*Main] -- > run p4 -- ("hi",4) -- ("ho",4) -- ("hi",4) -- [*Main] -- > run p4' -- Right ("hi",2) -- Right ("hi",2) -- Right ("ho",2) -- ("hi",4) -- Right ("ho",2) -- Right ("hi",2) -- ("ho",4) -- Right ("hi",2) -- Left "hi" -- ("hi",4) -- "hi" -- You received this message because you are subscribed to the Google Groups "Haskell Pipes" group. To unsubscribe from this group and stop receiving emails from it, send an email to haskell-pipes+unsubscr...@googlegroups.com. To post to this group, send email to haskell-pipes@googlegroups.com.