packages feed

pipes-parse 2.0.0 → 2.0.1

raw patch · 2 files changed

+69/−12 lines, 2 filesdep ~free

Dependency ranges changed: free

Files

pipes-parse.cabal view
@@ -1,5 +1,5 @@ Name: pipes-parse-Version: 2.0.0+Version: 2.0.1 Cabal-Version: >=1.8.0.2 Build-Type: Simple License: BSD3@@ -30,7 +30,7 @@     HS-Source-Dirs: src     Build-Depends:         base         >= 4       && < 5  ,-        free         >= 3.1     && < 3.5,+        free         >= 3.1     && < 4.2,         pipes        >= 4.0     && < 4.1,         transformers >= 0.2.0.0 && < 0.4     Exposed-Modules: Pipes.Parse
src/Pipes/Parse.hs view
@@ -8,8 +8,8 @@      * The monadic approach, using parser combinators -    The top half of this module provides the list-like approach.  The key idea-    is that:+    The top half of this module provides the list-like approach, which is easier+    to use, but less powerful.  The key idea is that:  > -- '~' means "is analogous to" > Producer a m ()            ~   [a]@@ -64,10 +64,47 @@     `Producer` without concatenating elements together, preserving the laziness     of the underlying 'Producer'. -    The bottom half of this module contains the lower-level monadic parsing-    primitives.  These are more useful for `pipes` implementers, particularly-    for building splitters.  I recommend that application developers use the-    list-like style whenever possible.+    The bottom half of this module lets you implement your own list-like+    transformations using monadic parsers.++    For example, if you wanted to repeatedly sum every 3 elements and yield the+    result, you would write:++> import Control.Monad (unless)+> import Pipes+> import qualified Pipes.Prelude as P+> import Pipes.Parse+>+> sum3 :: (Monad m, Num a) => Producer a (StateT (Producer a m ()) m) ()+> sum3 = do+>     eof <- lift isEndOfInput+>     unless eof $ do+>         n <- lift $ P.sum (input >-> P.take 3)+>         yield n+>         sum3++    When you are done building the parser, you convert your parser to a+    list-like function using `evalStateP`:++> import Pipes.Lift (evalStateP)+>+> -- sum3'  ~  (Num a) => [a] -> [a]+>+> sum3' :: (Monad m, Num a) => Producer a m () -> Producer a m ()+> sum3' p = evalStateP p sum3++    ... then apply it to the `Producer` you want to transform:++>>> runEffect $ sum3' (P.readLn >-> P.takeWhile (/= 0)) >-> P.print+1<Enter>+4<Enter>+5<Enter>+10+2<Enter>+0<Enter>+2+>>>+ -}  {-# LANGUAGE RankNTypes #-}@@ -80,6 +117,7 @@      -- * Transformations     takeFree,+    dropFree,      -- * Joiners     concat,@@ -107,12 +145,11 @@  import Control.Applicative ((<$>), (<$)) import qualified Control.Monad.Trans.Free as F-import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Free (FreeF(Pure, Free), FreeT(FreeT, runFreeT)) import qualified Control.Monad.Trans.State.Strict as S import Control.Monad.Trans.State.Strict (     StateT(StateT, runStateT), evalStateT, execStateT )-import Pipes (Producer, Pipe, await, yield, next, (>->), Producer')+import Pipes import Pipes.Lift (runStateP) import qualified Pipes.Prelude as P import Prelude hiding (concat, takeWhile)@@ -177,7 +214,7 @@             Pure r -> return r             Free p -> do                 f' <- p-                concat f'+                loop f' {-# INLINABLE concat #-}  {-| Join a 'FreeT'-delimited stream of 'Producer's into a single 'Producer' by@@ -205,7 +242,7 @@                 go1 f' {-# INLINABLE intercalate #-} --- | @(take n)@ only keeps the first @n@ functor layers of a 'FreeT'+-- | @(takeFree n)@ only keeps the first @n@ functor layers of a 'FreeT' takeFree :: (Functor f, Monad m) => Int -> FreeT f m () -> FreeT f m () takeFree = go   where@@ -218,6 +255,26 @@                 Free w  -> return (Free (fmap (go $! n - 1) w))         else return () {-# INLINABLE takeFree #-}++{-| @(dropFree n)@ peels off the first @n@ layers of a 'FreeT'++    Use carefully: the peeling off is not free.   This runs the first @n@+    layers, just discarding everything they produce.+-}+dropFree+    :: (Monad m) => Int -> FreeT (Producer a m) m r -> FreeT (Producer a m) m r+dropFree = go+  where+    go n ft+        | n <= 0 = ft+        | otherwise = FreeT $ do+            ff <- runFreeT ft+            case ff of+                Pure _ -> return ff+                Free f -> do+                    ft' <- runEffect $ for f discard+                    runFreeT $ go (n-1) ft'+{-# INLINABLE dropFree #-}  {- $lowlevel     @pipes-parse@ handles end-of-input and pushback by storing a 'Producer' in