packages feed

fusion 0.1.1 → 0.1.2

raw patch · 2 files changed

+135/−77 lines, 2 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Fusion: getListT :: ListT m a -> Stream a m ()
- Fusion: getStepList :: StepList s r a -> Step s a r
- Fusion: instance (Monad m, Applicative m) => Applicative (ListT m)
- Fusion: instance (Monad m, Applicative m) => Applicative (Stream a m)
- Fusion: instance (Monad m, Applicative m) => Monad (ListT m)
- Fusion: instance Functor (Step s a)
- Fusion: instance Functor (StepList s r)
- Fusion: instance Functor m => Functor (ListT m)
- Fusion: instance Functor m => Functor (Stream a m)
- Fusion: instance MonadTrans (Stream a)
- Fusion: instance Show a => Show (Stream a Identity r)
- Fusion: runEffect :: Monad m => Stream a m r -> m r
+ Fusion: [getListT] :: ListT m a -> Stream a m ()
+ Fusion: [getStepList] :: StepList s r a -> Step s a r
+ Fusion: dropS :: Monad m => Int -> Stream a m r -> Stream a m ()
+ Fusion: filterS :: Functor m => (a -> Bool) -> Stream a m r -> Stream a m r
+ Fusion: instance (GHC.Base.Monad m, GHC.Base.Applicative m) => GHC.Base.Applicative (Fusion.ListT m)
+ Fusion: instance (GHC.Base.Monad m, GHC.Base.Applicative m) => GHC.Base.Applicative (Fusion.Stream a m)
+ Fusion: instance (GHC.Base.Monad m, GHC.Base.Applicative m) => GHC.Base.Monad (Fusion.ListT m)
+ Fusion: instance Control.Monad.Trans.Class.MonadTrans (Fusion.Stream a)
+ Fusion: instance GHC.Base.Functor (Fusion.Step s a)
+ Fusion: instance GHC.Base.Functor (Fusion.StepList s r)
+ Fusion: instance GHC.Base.Functor m => GHC.Base.Functor (Fusion.ListT m)
+ Fusion: instance GHC.Base.Functor m => GHC.Base.Functor (Fusion.Stream a m)
+ Fusion: instance GHC.Show.Show a => GHC.Show.Show (Fusion.Stream a Data.Functor.Identity.Identity r)
+ Fusion: runStream :: Monad m => Stream a m r -> m r
+ Fusion: runStream_ :: Monad m => Stream Void m r -> m r
- Fusion: Stream :: (s -> m (Step s a r)) -> m s -> Stream a m r
+ Fusion: Stream :: (s -> m (Step s a r)) -> s -> Stream a m r
- Fusion: bracketS :: (Monad m, MonadMask m, MonadSafe m) => Base m s -> (s -> Base m ()) -> (forall r. s -> (a -> s -> m r) -> (s -> m r) -> m r -> m r) -> Stream a m ()
+ Fusion: bracketS :: (Monad m, MonadMask (Base m), MonadSafe m) => Base m s -> (s -> Base m ()) -> (forall r. s -> (s -> a -> m r) -> (s -> m r) -> m r -> m r) -> Stream a m ()

Files

Fusion.hs view
@@ -1,8 +1,11 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE GADTs #-}+{-# LANGUAGE TupleSections #-}  module Fusion     (@@ -11,9 +14,9 @@     -- * StepList     , StepList(..)     -- * Stream-    , Stream(..), mapS, concatS, fromList, fromListM-    , toListS, lazyToListS, runEffect, emptyStream-    , bracketS, next+    , Stream(..), mapS, filterS, dropS, concatS, fromList, fromListM+    , toListS, lazyToListS, runStream, runStream_+    , emptyStream, bracketS, next     -- * StreamList     , ListT(..), concatL     -- * Pipes@@ -31,6 +34,12 @@ import Pipes.Safe import System.IO.Unsafe +#define PHASE_FUSED [1]+#define PHASE_INNER [0]++#define INLINE_FUSED INLINE PHASE_FUSED+#define INLINE_INNER INLINE PHASE_INNER+ -- Step  -- | A simple stepper, as suggested by Duncan Coutts in his Thesis paper,@@ -51,127 +60,175 @@ -- Stream  data Stream a m r where-    Stream :: (s -> m (Step s a r)) -> m s -> Stream a m r+    Stream :: (s -> m (Step s a r)) -> s -> Stream a m r  instance Show a => Show (Stream a Identity r) where     show xs = "Stream " ++ show (runIdentity (toListS xs))  instance Functor m => Functor (Stream a m) where     fmap f (Stream k m) = Stream (fmap (fmap f) . k) m-    {-# INLINE fmap #-}+    {-# INLINE_FUSED fmap #-}  instance (Monad m, Applicative m) => Applicative (Stream a m) where-    pure x = Stream (pure . Done) (pure x)-    {-# INLINE pure #-}-    sf <*> sx = Stream (pure . Done) (runEffect sf <*> runEffect sx)-    {-# INLINE (<*>) #-}+    pure = Stream (pure . Done)+    {-# INLINE_FUSED pure #-}+    sf <*> sx = Stream (\() -> Done <$> (runStream sf <*> runStream sx)) ()+    {-# INLINE_FUSED (<*>) #-}  instance MonadTrans (Stream a) where-    lift = Stream (return . Done)-    {-# INLINE lift #-}+    lift = Stream (Done `liftM`)+    {-# INLINE_FUSED lift #-} +(<&>) :: Functor f => f a -> (a -> b) -> f b+(<&>) = flip (<$>)+{-# INLINE (<&>) #-}+ -- | Map over the values produced by a stream. -- -- >>> mapS (+1) (fromList [1..3]) :: Stream Int Identity () -- Stream [2,3,4] mapS :: Functor m => (a -> b) -> Stream a m r -> Stream b m r-mapS f (Stream s i) = Stream (fmap go . s) i+mapS f (Stream step i) = Stream step' i   where-    go (Done r)     = Done r-    go (Skip s')    = Skip s'-    go (Yield s' a) = Yield s' (f a)-{-# INLINE mapS #-}+    {-# INLINE_INNER step' #-}+    step' s = step s <&> \case+        Done r     -> Done r+        Skip s'    -> Skip s'+        Yield s' a -> Yield s' (f a)+{-# INLINE_FUSED mapS #-} +filterS :: Functor m => (a -> Bool) -> Stream a m r -> Stream a m r+filterS p (Stream step i) = Stream step' i+  where+    {-# INLINE_INNER step' #-}+    step' s = step s <&> \case+        Done r     -> Done r+        Skip s'    -> Skip s'+        Yield s' a | p a -> Yield s' a+                   | otherwise -> Skip s'+{-# INLINE_FUSED filterS #-}++dropS :: Monad m => Int -> Stream a m r -> Stream a m ()+dropS n (Stream step i) = Stream step' (i, Just n)+  where+    {-# INLINE_INNER step' #-}+    step' (s, Just n')+        | n' > 0 = step s <&> \case+            Yield s' _ -> Skip (s', Just (n'-1))+            Skip  s'   -> Skip (s', Just n')+            Done  _    -> Done ()+        | otherwise = return $ Skip (s, Nothing)++    step' (s, Nothing) = step s <&> \case+        Yield s' x -> Yield (s', Nothing) x+        Skip  s'   -> Skip  (s', Nothing)+        Done _     -> Done ()+{-# INLINE_FUSED dropS #-}+ concatS :: Monad m => Stream (Stream a m r) m r -> Stream a m r-concatS (Stream xs i) =-    Stream (\case Left  s       -> xs s >>= go Nothing-                  Right (st, t) -> go (Just t) st)-           (Left `liftM` i)+concatS (Stream step i) = Stream step' (Left i)   where-    go _ (Done r) = return $ Done r-    go _ (Skip s) = return $ Skip (Left s)+    {-# INLINE_INNER step' #-}+    step' (Left s) = step s >>= \case+        Done r     -> return $ Done r+        Skip s'    -> return $ Skip (Left s')+        Yield s' a -> step' (Right (s',a)) -    go Nothing e@(Yield _ z)              = go (Just z) e-    go (Just (Stream ys j)) e@(Yield s _) = go' `liftM` (j >>= ys)-      where-        go' (Done _)    = Skip (Left s)-        go' (Skip s')   = Skip (Right (e, Stream ys (return s')))-        go' (Yield s' a) = Yield (Right (e, Stream ys (return s'))) a-{-# SPECIALIZE concatS :: Stream (Stream a IO r) IO r -> Stream a IO r #-}+    step' (Right (s, Stream inner j)) = inner j <&> \case+        Done _     -> Skip (Left s)+        Skip j'    -> Skip (Right (s, Stream inner j'))+        Yield j' a -> Yield (Right (s, Stream inner j')) a+{-# INLINE_FUSED concatS #-}  fromList :: Foldable f => Applicative m => f a -> Stream a m ()-fromList = Stream (\case []     -> pure $ Done ()-                         (x:xs) -> pure $ Yield xs x) . pure . toList-{-# INLINE fromList #-}+fromList = Stream (pure . step) . toList+  where+    {-# INLINE_INNER step #-}+    step []     = Done ()+    step (x:xs) = Yield xs x+{-# INLINE_FUSED fromList #-}  fromListM :: (Monad m, Foldable f) => m (f a) -> Stream a m ()-fromListM xs = Stream (\case []     -> return $ Done ()-                             (y:ys) -> return $ Yield ys y)-                      (toList `liftM` xs)-{-# INLINE fromListM #-}+fromListM = Stream (step `liftM`) . liftM toList+  where+    {-# INLINE_INNER step #-}+    step []     = Done ()+    step (y:ys) = Yield (return ys) y+{-# INLINE_FUSED fromListM #-} -runEffect :: Monad m => Stream a m r -> m r-runEffect (Stream f i) = i >>= f >>= go+runStream :: Monad m => Stream a m r -> m r+runStream (Stream step i) = step' i   where-    go (Done r)    = return r-    go (Skip s)    = f s >>= go-    go (Yield s _) = f s >>= go-{-# INLINE runEffect #-}+    {-# INLINE_INNER step' #-}+    step' s = step s >>= \case+        Done r     -> return r+        Skip s'    -> step' s'+        Yield s' _ -> step' s'+{-# INLINE runStream #-} +runStream_ :: Monad m => Stream Void m r -> m r+runStream_ (Stream step i) = step' i+  where+    {-# INLINE_INNER step' #-}+    step' s = step s >>= \case+        Done r    -> return r+        Skip s'   -> step' s'+        Yield _ a -> absurd a+{-# INLINE runStream_ #-}+ toListS :: Monad m => Stream a m r -> m [a]-toListS (Stream f i) = i >>= f >>= go+toListS (Stream step i) = step' i   where-    go (Done _)   = return []-    go (Skip s)    = f s >>= go-    go (Yield s a) = f s >>= liftM (a:) . go+    {-# INLINE_INNER step' #-}+    step' s = step s >>= \case+        Done _     -> return []+        Skip s'    -> step' s'+        Yield s' a -> liftM (a:) (step' s') {-# INLINE toListS #-}  lazyToListS :: Stream a IO r -> IO [a]-lazyToListS (Stream f i) = i >>= f >>= go+lazyToListS (Stream step i) = step' i   where-    go (Done _)   = return []-    go (Skip s)    = f s >>= go-    go (Yield s a) = f s >>= liftM (a:) . unsafeInterleaveIO . go+    {-# INLINE_INNER step' #-}+    step' s = step s >>= \case+        Done _     -> return []+        Skip s'    -> step' s'+        Yield s' a -> liftM (a:) (unsafeInterleaveIO (step' s')) {-# INLINE lazyToListS #-}  emptyStream :: (Monad m, Applicative m) => Stream Void m () emptyStream = pure ()-{-# INLINE emptyStream #-}+{-# INLINE CONLIKE emptyStream #-} -bracketS :: (Monad m, MonadMask m, MonadSafe m)+bracketS :: (Monad m, MonadMask (Base m), MonadSafe m)          => Base m s          -> (s -> Base m ())-         -> (forall r. s -> (a -> s -> m r) -> (s -> m r) -> m r -> m r)+         -> (forall r. s -> (s -> a -> m r) -> (s -> m r) -> m r -> m r)          -> Stream a m ()-bracketS i f step = Stream go $ mask $ \_unmask -> do-    s   <- liftBase i+bracketS i f step = Stream step' $ mask $ \unmask -> do+    s   <- unmask $ liftBase i     key <- register (f s)     return (s, key)   where-    go (s, key) =-        step s (\a s' -> return $ Yield (s', key) a)-               (\s'   -> return $ Skip (s', key))-               (release key >> (const (Done ()) `liftM` liftBase (f s)))-{--{-# SPECIALIZE bracketS-      :: IO s-      -> (s -> IO ())-      -> (forall r. s -> (a -> s -> SafeT IO r)-           -> (s -> SafeT IO r)-           -> SafeT IO r-           -> SafeT IO r)-      -> Stream a (SafeT IO) () #-}--}+    {-# INLINE_INNER step' #-}+    step' mx = mx >>= \(s, key) -> step s+        (\s' a -> return $ Yield (return (s', key)) a)+        (\s'   -> return $ Skip  (return (s', key)))+        (mask $ \unmask -> do+              unmask $ liftBase $ f s+              release key+              return $ Done ())+{-# INLINE_FUSED bracketS #-}  next :: Monad m => Stream a m r -> m (Either r (a, Stream a m r))-next (Stream xs i) = do-    s <- i-    x <- xs s-    case x of+next (Stream step i) = step' i+  where+    {-# INLINE_INNER step' #-}+    step' s = step s >>= \case         Done r     -> return $ Left r-        Skip s'    -> next (Stream xs (return s'))-        Yield s' a -> return $ Right (a, Stream xs (return s'))-{-# SPECIALIZE next :: Stream a IO r -> IO (Either r (a, Stream a IO r)) #-}+        Skip s'    -> step' s'+        Yield s' a -> return $ Right (a, Stream step s')+{-# INLINE next #-}  -- ListT 
fusion.cabal view
@@ -1,5 +1,5 @@ name:                fusion-version:             0.1.1+version:             0.1.2 synopsis:            Effectful streaming library based on shortcut fusion techniques description:         Effectful streaming library based on shortcut fusion techniques homepage:            https://github.com/jwiegley/fusion@@ -15,6 +15,7 @@ library   exposed-modules:     Fusion   other-extensions:    DeriveFunctor, LambdaCase, RankNTypes, GADTs+  ghc-options:         -O2   build-depends:              base         >=4.7 && <5     , transformers >=0.3 && <0.5