packages feed

simple-pipe (empty) → 0.0.0.0

raw patch · 5 files changed

+261/−0 lines, 5 filesdep +basedep +lifted-basedep +monad-controlsetup-changed

Dependencies added: base, lifted-base, monad-control, monads-tf

Files

+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2014, Yoshikuni Jujo+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++  * Redistributions of source code must retain the above copyright notice,+    this list of conditions and the following disclaimer.++  * Redistributions in binary form must reproduce the above copyright+    notice, this list of conditions and the following disclaimer in the+    documentation and/or other materials provided with the distribution.++  * Neither the name of the Yoshikuni Jujo nor the names of its+    contributors may be used to endorse or promote products derived from+    this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVEN SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,1 @@+import Distribution.Simple; main = defaultMain
+ examples/upperFile.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE PackageImports #-}++import Data.Pipe+import Data.Char+import System.IO+import "monads-tf" Control.Monad.Trans++main :: IO ()+main = do+	_ <- runPipe $+		readFileP "sample.txt"+			=$= takeP 3+			=$= convert (map toUpper)+			=$= writeString+	return ()++readFileP :: FilePath -> Pipe () String IO ()+readFileP fp = bracket (openFile fp ReadMode) hClose hRead++hRead :: Handle -> Pipe () String IO ()+hRead h = do+	eof <- lift $ hIsEOF h+	if eof then return () else do+		l <- lift $ hGetLine h+		yield l+		hRead h++writeString :: Pipe String () IO ()+writeString = do+	ms <- await+	case ms of+		Just s -> lift (putStrLn s) >> writeString+		_ -> return ()++convert :: Monad m => (a -> b) -> Pipe a b m ()+convert f = do+	mx <- await+	case mx of+		Just x -> yield (f x) >> convert f+		_ -> return ()++takeP :: Monad m => Int -> Pipe a a m ()+takeP 0 = return ()+takeP n = do+	mx <- await+	case mx of+		Just x -> yield x >> takeP (n - 1)+		_ -> return ()
+ simple-pipe.cabal view
@@ -0,0 +1,98 @@+build-type:	Simple+cabal-version:	>= 1.8++name:		simple-pipe+version:	0.0.0.0+stability:	Experimental+author:		Yoshikuni Jujo <PAF01143@nifty.ne.jp>+maintainer:	Yoshikuni Jujo <PAF01143@nifty.ne.jp>+homepage:	https://github.com/YoshikuniJujo/simple-pipe/wiki++license:	BSD3+license-file:	LICENSE++category:	Data+synopsis:	simple pipeline library like conduit+description:+    .+    examples/upperFile.hs+    .+    * read file (sample.txt)+    .+    * take 3 lines+    .+    * to upper all lines+    .+    * write to stdout+    .+    extensions+    .+    .+    * PackageImports+    .+    > import Data.Pipe+    > import Data.Char+    > import System.IO+    > import "monads-tf" Control.Monad.Trans+    >+    > main :: IO ()+    > main = do+    > 	_ <- runPipe $ readFileP "sample.txt"+    >		=$= takeP 3+    >		=$= convert (map toUpper)+    >		=$= writeString+    > 	return ()+    >+    > readFileP :: FilePath -> Pipe () String IO ()+    > readFileP fp = bracket (openFile fp ReadMode) hClose hRead+    >+    > hRead :: Handle -> Pipe () String IO ()+    > hRead h = do+    > 	eof <- lift $ hIsEOF h+    > 	if eof then return () else do+    > 		l <- lift $ hGetLine h+    > 		yield l+    > 		hRead h+    >+    > writeString :: Pipe String () IO ()+    > writeString = do+    > 	ms <- await+    > 	case ms of+    > 		Just s -> lift (putStrLn s) >> writeString+    > 		_ -> return ()+    >+    > convert :: Monad m => (a -> b) -> Pipe a b m ()+    > convert f = do+    > 	mx <- await+    > 	case mx of+    > 		Just x -> yield (f x) >> convert f+    > 		_ -> return ()+    >+    > takeP :: Monad m => Int -> Pipe a a m ()+    > takeP 0 = return ()+    > takeP n = do+    >	mx <- await+    >	case mx of+    >		Just x -> yield x >> takeP (n - 1)+    >		_ -> return ()+    .++extra-source-files:+    examples/upperFile.hs++source-repository	head+    type:	git+    location:	git://github.com/YoshikuniJujo/forest.git++source-repository	this+    type:	git+    location:	git://github.com/YoshikuniJujo/forest.git+    tag:	simple-pipe-0.0.0.0++library+    hs-source-dirs:	src+    exposed-modules:	Data.Pipe+    build-depends:+        base == 4.*, monad-control == 0.3.*, lifted-base == 0.2.*,+        monads-tf == 0.1.*+    ghc-options:	-Wall
+ src/Data/Pipe.hs view
@@ -0,0 +1,87 @@+{-# LANGUAGE FlexibleContexts, RankNTypes, PackageImports #-}++module Data.Pipe (+	PipeClass(..), Pipe, runPipe, finalize, finally, bracket ) where++import Control.Applicative+import Control.Monad+import Control.Exception.Lifted (onException)+import Control.Monad.Trans.Control+import "monads-tf" Control.Monad.Trans++class PipeClass p where+	(=$=) :: Monad m => p a b m x -> p b c m y -> p a c m y+	yield :: Monad m => o -> p i o m ()+	await :: Monad m => p i o m (Maybe i)++data Pipe i o m r+	= Ready (m ()) o (Pipe i o m r)+	| Need (m ()) (Maybe i -> Pipe i o m r)+	| Done (m ()) r+	| Make (m ()) (m (Pipe i o m r))++finalizer :: Pipe i o m r -> m ()+finalizer (Ready f _ _) = f+finalizer (Need f _) = f+finalizer (Done f _) = f+finalizer (Make f _) = f++instance PipeClass Pipe where+	p =$= Done f r = Done (finalizer p >> f) r+	p =$= Ready f o p' = Ready f o $ p =$= p'+	Need f n =$= p = Need f $ \i -> n i =$= p+	Ready _ o p =$= Need _ n = p =$= n (Just o)+	Done f r =$= Need f' n =+		Done (return ()) r =$= Make f' (f >> return (n Nothing))+	Make f m =$= p = Make f $ (=$= p) `liftM` m+	p =$= Make f m = Make f $ (p =$=) `liftM` m++	yield x = Ready (return ()) x (return ())+	await = Need (return ()) return++instance Monad m => Monad (Pipe i o m) where+	Ready f o p >>= k = Ready f o $ p >>= k+	Need f n >>= k = Need f $ \i -> n i >>= k+--	Done f r >>= k = Make (return ()) $ f >> return (k r)+	Done _ r >>= k = k r+	Make f m >>= k = Make f $ (>>= k) `liftM` m+	return = Done (return ())++instance Monad m => Functor (Pipe i o m) where+	fmap = (=<<) . (return .)++instance Monad m => Applicative (Pipe i o m) where+	pure = return+	(<*>) = liftM2 id++instance MonadTrans (Pipe i o) where+	lift = liftP++runPipe :: Monad m => Pipe i o m r -> m (Maybe r)+runPipe (Done f r) = f >> return (Just r)+runPipe (Make _ m) = runPipe =<< m+runPipe _ = return Nothing++liftP :: Monad m => m a -> Pipe i o m a+liftP m = Make (return ()) $ Done (return ()) `liftM` m++bracket :: MonadBaseControl IO m =>+	m a -> (a -> m b) -> (a -> Pipe i o m r) -> Pipe i o m r+bracket o c p = do+	h <- liftP o+	p h `finally` (c h >> return ())++finalize :: Monad m => Pipe i o m r -> m b -> Pipe i o m r+finalize (Ready _ o p) f = Ready (f >> return ()) o $ finalize p f+finalize (Need _ n) f = Need (f >> return ()) $ \i -> finalize (n i) f+finalize (Done _ r) f = Done (f >> return ()) r+finalize (Make _ m) f = Make (f >> return ()) $ flip finalize f `liftM` m++finally :: MonadBaseControl IO m => Pipe i o m r -> m b -> Pipe i o m r+finally p f = finalize (mapMake (`onException` f) p) f++mapMake :: Monad m => (forall a . m a -> m a) -> Pipe i o m r -> Pipe i o m r+mapMake k (Ready f o p) = Ready f o $ mapMake k p+mapMake k (Need f n) = Need f $ \i -> mapMake k $ n i+mapMake _ (Done f r) = Done f r+mapMake k (Make f m) = Make f . k $ mapMake k `liftM` m