{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE EmptyDataDecls #-} module Pipes.Transduce ( -- * Producer folds Fold1 , fold1 , fold1Fallibly -- ** Building producer folds -- *** From foldl folds -- $foldl , withFold , withFoldIO , withFallibleFold -- *** From consumers -- $consumers , withConsumer , withConsumer' , withConsumerM , withConsumerM' , withSafeConsumer , withFallibleConsumer -- *** From parsers -- $parsers , withParser , withParserM -- *** From continuations -- $continuations , withCont , withCont' , withFallibleCont , withFallibleCont' -- *** From Stream-accepting continuations -- $streamingcontinuations , withStreamCont , withStreamCont' , withFallibleStreamCont , withFallibleStreamCont' -- * Fold transducers , Transducer , Delimited , Continuous , transduce1 -- ** Building fold transducers , mapper , fallibleMapper , mapperFoldable , mapperEnumerable , transducer , fallibleTransducer -- ** Transducer group operations , delimit , groups , folds , concats , intercalates -- * Multiple producer folds , Fold2 , fold2 , fold2Fallibly -- ** Building multiple producer folds , liftFirst , liftSecond , separated , combined -- * Utilities , intoList , trip , tripx -- * Re-exports , runExceptT , throwE , next ) where import Control.Exception import qualified Control.Foldl as L import Control.Monad.Trans.Except(runExceptT,throwE) import Pipes(next) import Pipes.Transduce.Internal {- $setup >>> :set -XOverloadedStrings >>> import qualified Data.Text as T >>> import qualified Data.Text.Lazy as TL >>> import Control.Applicative >>> import Control.Monad >>> import qualified Control.Foldl as L >>> import Pipes.Transduce >>> import qualified Pipes.Transduce as PT -} {-| Fail if the 'Producer' produces anything at all. The error value is what came out of the 'Producer'. >>> PT.fold1Fallibly trip (mapM_ yield ['z']) Left 'z' >>> PT.fold1Fallibly trip (mapM_ yield []) Right ((),()) -} trip :: Fold1 b b () trip = withFallibleCont' $ \producer -> do n <- next producer return $ case n of Left r -> Right ((),r) Right (b,_) -> Left b {-| Throw an exception if the 'Producer' produces anything at all __/BEWARE!/__ This 'Transducer may throw 'AssertionFailed'. __/BEWARE!/__ >>> PT.fold1Fallibly PT.tripx (mapM_ yield ['z']) *** Exception: tripx -} tripx :: Fold1 b e () tripx = withFallibleCont' $ \producer -> do n <- next producer case n of Left r -> return (Right ((),r)) Right _ -> throwIO (AssertionFailed "tripx") intoList :: Fold1 b e [b] intoList = withFold L.list {- $foldl 'Fold1' values can be created out of the more general folds of the @foldl@ library, which are producer-agnostic. -} {- $consumers 'Fold1' values can be created out of 'Consumer's from the @pipes@ library. -} {- $parsers 'Fold1' values can be created out of 'Parser's from the @pipes-parse@ library. -} {- $continuations The most general way of constructing 'Fold1' values is from an arbitrary function that consumes a 'Producer'. -} {- $streamingcontinuations Variants of the continuation-accepting functions where the continuations consume 'Stream's from the @streaming@ package, instead of 'Producer's from @pipes@. -}