mirror of
https://github.com/composewell/streamly.git
synced 2024-09-17 14:37:27 +03:00
Use Applicative instead of Monad where possible
Only refactoring, no functional change. In Unfold, StreamD and StreamK. Also fix a few hlint issues.
This commit is contained in:
parent
ed2c32f99a
commit
d28e2313f1
@ -3,7 +3,6 @@ src/Streamly/Internal/Data/Stream/PreludeCommon.hs
|
|||||||
src/Streamly/Internal/Data/Stream/Serial.hs
|
src/Streamly/Internal/Data/Stream/Serial.hs
|
||||||
src/Streamly/Internal/Data/Stream/Zip.hs
|
src/Streamly/Internal/Data/Stream/Zip.hs
|
||||||
src/Streamly/Internal/Data/Stream/StreamK/Type.hs
|
src/Streamly/Internal/Data/Stream/StreamK/Type.hs
|
||||||
src/Streamly/Internal/Data/Stream/StreamD/Type.hs
|
|
||||||
src/Streamly/Internal/Data/Pipe/Type.hs
|
src/Streamly/Internal/Data/Pipe/Type.hs
|
||||||
src/Streamly/Internal/Data/SmallArray/Type.hs
|
src/Streamly/Internal/Data/SmallArray/Type.hs
|
||||||
src/Streamly/Internal/Unicode/Stream.hs
|
src/Streamly/Internal/Unicode/Stream.hs
|
||||||
|
@ -92,6 +92,7 @@ import Control.Applicative (liftA2)
|
|||||||
import Control.Monad (when)
|
import Control.Monad (when)
|
||||||
import Control.Monad.Catch (MonadThrow, throwM)
|
import Control.Monad.Catch (MonadThrow, throwM)
|
||||||
import Control.Monad.Trans.Class (lift, MonadTrans)
|
import Control.Monad.Trans.Class (lift, MonadTrans)
|
||||||
|
import Data.Functor (($>))
|
||||||
import Data.Functor.Identity (Identity(..))
|
import Data.Functor.Identity (Identity(..))
|
||||||
import Fusion.Plugin.Types (Fuse(..))
|
import Fusion.Plugin.Types (Fuse(..))
|
||||||
import GHC.Base (build)
|
import GHC.Base (build)
|
||||||
@ -134,22 +135,22 @@ pattern Stream step state <- (unShare -> UnStream step state)
|
|||||||
|
|
||||||
-- | An empty 'Stream' with a side effect.
|
-- | An empty 'Stream' with a side effect.
|
||||||
{-# INLINE_NORMAL nilM #-}
|
{-# INLINE_NORMAL nilM #-}
|
||||||
nilM :: Monad m => m b -> Stream m a
|
nilM :: Applicative m => m b -> Stream m a
|
||||||
nilM m = Stream (\_ _ -> m >> return Stop) ()
|
nilM m = Stream (\_ _ -> m $> Stop) ()
|
||||||
|
|
||||||
{-# INLINE_NORMAL consM #-}
|
{-# INLINE_NORMAL consM #-}
|
||||||
consM :: Monad m => m a -> Stream m a -> Stream m a
|
consM :: Applicative m => m a -> Stream m a -> Stream m a
|
||||||
consM m (Stream step state) = Stream step1 Nothing
|
consM m (Stream step state) = Stream step1 Nothing
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step1 #-}
|
{-# INLINE_LATE step1 #-}
|
||||||
step1 _ Nothing = m >>= \x -> return $ Yield x (Just state)
|
step1 _ Nothing = (`Yield` Just state) <$> m
|
||||||
step1 gst (Just st) = do
|
step1 gst (Just st) = do
|
||||||
r <- step gst st
|
(\case
|
||||||
return $
|
|
||||||
case r of
|
|
||||||
Yield a s -> Yield a (Just s)
|
Yield a s -> Yield a (Just s)
|
||||||
Skip s -> Skip (Just s)
|
Skip s -> Skip (Just s)
|
||||||
Stop -> Stop
|
Stop -> Stop) <$> step gst st
|
||||||
|
|
||||||
-- | Does not fuse, has the same performance as the StreamK version.
|
-- | Does not fuse, has the same performance as the StreamK version.
|
||||||
{-# INLINE_NORMAL uncons #-}
|
{-# INLINE_NORMAL uncons #-}
|
||||||
@ -172,17 +173,18 @@ data UnfoldState s = UnfoldNothing | UnfoldJust s
|
|||||||
-- | Convert an 'Unfold' into a 'Stream' by supplying it a seed.
|
-- | Convert an 'Unfold' into a 'Stream' by supplying it a seed.
|
||||||
--
|
--
|
||||||
{-# INLINE_NORMAL unfold #-}
|
{-# INLINE_NORMAL unfold #-}
|
||||||
unfold :: Monad m => Unfold m a b -> a -> Stream m b
|
unfold :: Applicative m => Unfold m a b -> a -> Stream m b
|
||||||
unfold (Unfold ustep inject) seed = Stream step UnfoldNothing
|
unfold (Unfold ustep inject) seed = Stream step UnfoldNothing
|
||||||
where
|
|
||||||
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step _ UnfoldNothing = inject seed >>= return . Skip . UnfoldJust
|
step _ UnfoldNothing = Skip . UnfoldJust <$> inject seed
|
||||||
step _ (UnfoldJust st) = do
|
step _ (UnfoldJust st) = do
|
||||||
r <- ustep st
|
(\case
|
||||||
return $ case r of
|
|
||||||
Yield x s -> Yield x (UnfoldJust s)
|
Yield x s -> Yield x (UnfoldJust s)
|
||||||
Skip s -> Skip (UnfoldJust s)
|
Skip s -> Skip (UnfoldJust s)
|
||||||
Stop -> Stop
|
Stop -> Stop) <$> ustep st
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
-- From Values
|
-- From Values
|
||||||
@ -199,12 +201,14 @@ fromPure x = Stream (\_ s -> pure $ step undefined s) True
|
|||||||
|
|
||||||
-- | Create a singleton 'Stream' from a monadic action.
|
-- | Create a singleton 'Stream' from a monadic action.
|
||||||
{-# INLINE_NORMAL fromEffect #-}
|
{-# INLINE_NORMAL fromEffect #-}
|
||||||
fromEffect :: Monad m => m a -> Stream m a
|
fromEffect :: Applicative m => m a -> Stream m a
|
||||||
fromEffect m = Stream step True
|
fromEffect m = Stream step True
|
||||||
where
|
|
||||||
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step _ True = m >>= \x -> return $ Yield x False
|
step _ True = (`Yield` False) <$> m
|
||||||
step _ False = return Stop
|
step _ False = pure Stop
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
-- From Containers
|
-- From Containers
|
||||||
@ -226,13 +230,13 @@ fromList = Stream step
|
|||||||
|
|
||||||
-- | Convert a CPS encoded StreamK to direct style step encoded StreamD
|
-- | Convert a CPS encoded StreamK to direct style step encoded StreamD
|
||||||
{-# INLINE_LATE fromStreamK #-}
|
{-# INLINE_LATE fromStreamK #-}
|
||||||
fromStreamK :: Monad m => K.Stream m a -> Stream m a
|
fromStreamK :: Applicative m => K.Stream m a -> Stream m a
|
||||||
fromStreamK = Stream step
|
fromStreamK = Stream step
|
||||||
where
|
where
|
||||||
step gst m1 =
|
step gst m1 =
|
||||||
let stop = return Stop
|
let stop = pure Stop
|
||||||
single a = return $ Yield a K.nil
|
single a = pure $ Yield a K.nil
|
||||||
yieldk a r = return $ Yield a r
|
yieldk a r = pure $ Yield a r
|
||||||
in K.foldStreamShared gst yieldk single stop m1
|
in K.foldStreamShared gst yieldk single stop m1
|
||||||
|
|
||||||
-- | Convert a direct style step encoded StreamD to a CPS encoded StreamK
|
-- | Convert a direct style step encoded StreamD to a CPS encoded StreamK
|
||||||
@ -261,7 +265,7 @@ toStreamK (Stream step state) = go state
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
{-# INLINE_NORMAL fold #-}
|
{-# INLINE_NORMAL fold #-}
|
||||||
fold :: (Monad m) => Fold m a b -> Stream m a -> m b
|
fold :: Monad m => Fold m a b -> Stream m a -> m b
|
||||||
fold fld strm = do
|
fold fld strm = do
|
||||||
(b, _) <- fold_ fld strm
|
(b, _) <- fold_ fld strm
|
||||||
return b
|
return b
|
||||||
@ -349,7 +353,7 @@ foldrMx fstep final convert (Stream step state) = convert $ go SPEC state
|
|||||||
--
|
--
|
||||||
{-# INLINE_NORMAL foldr #-}
|
{-# INLINE_NORMAL foldr #-}
|
||||||
foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
|
foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
|
||||||
foldr f z = foldrM (\a b -> liftA2 f (return a) b) (return z)
|
foldr f z = foldrM (liftA2 f . return) (return z)
|
||||||
|
|
||||||
-- this performs horribly, should not be used
|
-- this performs horribly, should not be used
|
||||||
{-# INLINE_NORMAL foldrS #-}
|
{-# INLINE_NORMAL foldrS #-}
|
||||||
@ -409,8 +413,8 @@ foldlMx' fstep begin done (Stream step state) =
|
|||||||
|
|
||||||
{-# INLINE foldlx' #-}
|
{-# INLINE foldlx' #-}
|
||||||
foldlx' :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> m b
|
foldlx' :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> m b
|
||||||
foldlx' fstep begin done m =
|
foldlx' fstep begin done =
|
||||||
foldlMx' (\b a -> return (fstep b a)) (return begin) (return . done) m
|
foldlMx' (\b a -> return (fstep b a)) (return begin) (return . done)
|
||||||
|
|
||||||
-- Adapted from the vector package.
|
-- Adapted from the vector package.
|
||||||
-- XXX implement in terms of foldlMx'?
|
-- XXX implement in terms of foldlMx'?
|
||||||
@ -576,17 +580,18 @@ instance Functor m => Functor (Stream m) where
|
|||||||
|
|
||||||
-- Adapted from the vector package.
|
-- Adapted from the vector package.
|
||||||
{-# INLINE_NORMAL take #-}
|
{-# INLINE_NORMAL take #-}
|
||||||
take :: Monad m => Int -> Stream m a -> Stream m a
|
take :: Applicative m => Int -> Stream m a -> Stream m a
|
||||||
take n (Stream step state) = n `seq` Stream step' (state, 0)
|
take n (Stream step state) = n `seq` Stream step' (state, 0)
|
||||||
where
|
|
||||||
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step' #-}
|
{-# INLINE_LATE step' #-}
|
||||||
step' gst (st, i) | i < n = do
|
step' gst (st, i) | i < n = do
|
||||||
r <- step gst st
|
(\case
|
||||||
return $ case r of
|
|
||||||
Yield x s -> Yield x (s, i + 1)
|
Yield x s -> Yield x (s, i + 1)
|
||||||
Skip s -> Skip (s, i)
|
Skip s -> Skip (s, i)
|
||||||
Stop -> Stop
|
Stop -> Stop) <$> step gst st
|
||||||
step' _ (_, _) = return Stop
|
step' _ (_, _) = pure Stop
|
||||||
|
|
||||||
-- Adapted from the vector package.
|
-- Adapted from the vector package.
|
||||||
{-# INLINE_NORMAL takeWhileM #-}
|
{-# INLINE_NORMAL takeWhileM #-}
|
||||||
@ -613,17 +618,20 @@ takeWhile f = takeWhileM (return . f)
|
|||||||
|
|
||||||
{-# INLINE_NORMAL concatAp #-}
|
{-# INLINE_NORMAL concatAp #-}
|
||||||
concatAp :: Functor f => Stream f (a -> b) -> Stream f a -> Stream f b
|
concatAp :: Functor f => Stream f (a -> b) -> Stream f a -> Stream f b
|
||||||
concatAp (Stream stepa statea) (Stream stepb stateb) = Stream step' (Left statea)
|
concatAp (Stream stepa statea) (Stream stepb stateb) =
|
||||||
where
|
Stream step' (Left statea)
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step' #-}
|
{-# INLINE_LATE step' #-}
|
||||||
step' gst (Left st) = fmap
|
step' gst (Left st) = fmap
|
||||||
(\r -> case r of
|
(\case
|
||||||
Yield f s -> Skip (Right (f, s, stateb))
|
Yield f s -> Skip (Right (f, s, stateb))
|
||||||
Skip s -> Skip (Left s)
|
Skip s -> Skip (Left s)
|
||||||
Stop -> Stop)
|
Stop -> Stop)
|
||||||
(stepa (adaptState gst) st)
|
(stepa (adaptState gst) st)
|
||||||
step' gst (Right (f, os, st)) = fmap
|
step' gst (Right (f, os, st)) = fmap
|
||||||
(\r -> case r of
|
(\case
|
||||||
Yield a s -> Yield (f a) (Right (f, os, s))
|
Yield a s -> Yield (f a) (Right (f, os, s))
|
||||||
Skip s -> Skip (Right (f,os, s))
|
Skip s -> Skip (Right (f,os, s))
|
||||||
Stop -> Skip (Left os))
|
Stop -> Skip (Left os))
|
||||||
@ -639,19 +647,17 @@ apSequence (Stream stepa statea) (Stream stepb stateb) =
|
|||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step gst (Left st) =
|
step gst (Left st) =
|
||||||
fmap
|
fmap
|
||||||
(\r ->
|
(\case
|
||||||
case r of
|
Yield _ s -> Skip (Right (s, stateb))
|
||||||
Yield _ s -> Skip (Right (s, stateb))
|
Skip s -> Skip (Left s)
|
||||||
Skip s -> Skip (Left s)
|
Stop -> Stop)
|
||||||
Stop -> Stop)
|
|
||||||
(stepa (adaptState gst) st)
|
(stepa (adaptState gst) st)
|
||||||
step gst (Right (ostate, st)) =
|
step gst (Right (ostate, st)) =
|
||||||
fmap
|
fmap
|
||||||
(\r ->
|
(\case
|
||||||
case r of
|
Yield b s -> Yield b (Right (ostate, s))
|
||||||
Yield b s -> Yield b (Right (ostate, s))
|
Skip s -> Skip (Right (ostate, s))
|
||||||
Skip s -> Skip (Right (ostate, s))
|
Stop -> Skip (Left ostate))
|
||||||
Stop -> Skip (Left ostate))
|
|
||||||
(stepb gst st)
|
(stepb gst st)
|
||||||
|
|
||||||
{-# INLINE_NORMAL apDiscardSnd #-}
|
{-# INLINE_NORMAL apDiscardSnd #-}
|
||||||
@ -664,19 +670,17 @@ apDiscardSnd (Stream stepa statea) (Stream stepb stateb) =
|
|||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step gst (Left st) =
|
step gst (Left st) =
|
||||||
fmap
|
fmap
|
||||||
(\r ->
|
(\case
|
||||||
case r of
|
Yield b s -> Skip (Right (s, stateb, b))
|
||||||
Yield b s -> Skip (Right (s, stateb, b))
|
Skip s -> Skip (Left s)
|
||||||
Skip s -> Skip (Left s)
|
Stop -> Stop)
|
||||||
Stop -> Stop)
|
|
||||||
(stepa gst st)
|
(stepa gst st)
|
||||||
step gst (Right (ostate, st, b)) =
|
step gst (Right (ostate, st, b)) =
|
||||||
fmap
|
fmap
|
||||||
(\r ->
|
(\case
|
||||||
case r of
|
Yield _ s -> Yield b (Right (ostate, s, b))
|
||||||
Yield _ s -> Yield b (Right (ostate, s, b))
|
Skip s -> Skip (Right (ostate, s, b))
|
||||||
Skip s -> Skip (Right (ostate, s, b))
|
Stop -> Skip (Left ostate))
|
||||||
Stop -> Skip (Left ostate))
|
|
||||||
(stepb (adaptState gst) st)
|
(stepb (adaptState gst) st)
|
||||||
|
|
||||||
instance Applicative f => Applicative (Stream f) where
|
instance Applicative f => Applicative (Stream f) where
|
||||||
@ -728,7 +732,7 @@ unfoldMany (Unfold istep inject) (Stream ostep ost) =
|
|||||||
i <- inject a
|
i <- inject a
|
||||||
i `seq` return (Skip (ConcatMapUInner o' i))
|
i `seq` return (Skip (ConcatMapUInner o' i))
|
||||||
Skip o' -> return $ Skip (ConcatMapUOuter o')
|
Skip o' -> return $ Skip (ConcatMapUOuter o')
|
||||||
Stop -> return $ Stop
|
Stop -> return Stop
|
||||||
|
|
||||||
step _ (ConcatMapUInner o i) = do
|
step _ (ConcatMapUInner o i) = do
|
||||||
r <- istep i
|
r <- istep i
|
||||||
|
@ -179,7 +179,7 @@ fromYieldK k = mkStream $ \_ _ sng _ -> k sng
|
|||||||
|
|
||||||
-- | Add a yield function at the head of the stream.
|
-- | Add a yield function at the head of the stream.
|
||||||
consK :: YieldK m a -> Stream m a -> Stream m a
|
consK :: YieldK m a -> Stream m a -> Stream m a
|
||||||
consK k r = mkStream $ \_ yld _ _ -> k (\x -> yld x r)
|
consK k r = mkStream $ \_ yld _ _ -> k (`yld` r)
|
||||||
|
|
||||||
-- XXX Build a stream from a repeating callback function.
|
-- XXX Build a stream from a repeating callback function.
|
||||||
|
|
||||||
@ -241,8 +241,8 @@ nil = mkStream $ \_ _ _ stp -> stp
|
|||||||
--
|
--
|
||||||
-- /Pre-release/
|
-- /Pre-release/
|
||||||
{-# INLINE_NORMAL nilM #-}
|
{-# INLINE_NORMAL nilM #-}
|
||||||
nilM :: Monad m => m b -> Stream m a
|
nilM :: Applicative m => m b -> Stream m a
|
||||||
nilM m = mkStream $ \_ _ _ stp -> m >> stp
|
nilM m = mkStream $ \_ _ _ stp -> m *> stp
|
||||||
|
|
||||||
{-# INLINE_NORMAL fromPure #-}
|
{-# INLINE_NORMAL fromPure #-}
|
||||||
fromPure :: a -> Stream m a
|
fromPure :: a -> Stream m a
|
||||||
@ -259,8 +259,8 @@ infixr 5 `consM`
|
|||||||
-- SPECIALIZE in the instance definition.
|
-- SPECIALIZE in the instance definition.
|
||||||
{-# INLINE consM #-}
|
{-# INLINE consM #-}
|
||||||
{-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
|
{-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
|
||||||
consM :: (Monad m) => m a -> Stream m a -> Stream m a
|
consM :: Monad m => m a -> Stream m a -> Stream m a
|
||||||
consM m r = MkStream $ \_ yld _ _ -> m >>= \a -> yld a r
|
consM m r = MkStream $ \_ yld _ _ -> m >>= (`yld` r)
|
||||||
|
|
||||||
-- XXX specialize to IO?
|
-- XXX specialize to IO?
|
||||||
{-# INLINE consMBy #-}
|
{-# INLINE consMBy #-}
|
||||||
@ -1270,30 +1270,29 @@ fromFoldableM = Prelude.foldr consM nil
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
{-# INLINE uncons #-}
|
{-# INLINE uncons #-}
|
||||||
uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
|
uncons :: Applicative m => Stream m a -> m (Maybe (a, Stream m a))
|
||||||
uncons m =
|
uncons m =
|
||||||
let stop = return Nothing
|
let stop = pure Nothing
|
||||||
single a = return (Just (a, nil))
|
single a = pure (Just (a, nil))
|
||||||
yieldk a r = return (Just (a, r))
|
yieldk a r = pure (Just (a, r))
|
||||||
in foldStream defState yieldk single stop m
|
in foldStream defState yieldk single stop m
|
||||||
|
|
||||||
{-# INLINE tail #-}
|
{-# INLINE tail #-}
|
||||||
tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
|
tail :: Applicative m => Stream m a -> m (Maybe (Stream m a))
|
||||||
tail =
|
tail =
|
||||||
let stop = return Nothing
|
let stop = pure Nothing
|
||||||
single _ = return $ Just nil
|
single _ = pure $ Just nil
|
||||||
yieldk _ r = return $ Just r
|
yieldk _ r = pure $ Just r
|
||||||
in foldStream defState yieldk single stop
|
in foldStream defState yieldk single stop
|
||||||
|
|
||||||
{-# INLINE init #-}
|
{-# INLINE init #-}
|
||||||
init :: Monad m => Stream m a -> m (Maybe (Stream m a))
|
init :: Applicative m => Stream m a -> m (Maybe (Stream m a))
|
||||||
init = go1
|
init = go1
|
||||||
where
|
where
|
||||||
go1 m1 = do
|
go1 m1 = do
|
||||||
r <- uncons m1
|
(\case
|
||||||
case r of
|
Nothing -> Nothing
|
||||||
Nothing -> return Nothing
|
Just (h, t) -> Just $ go h t) <$> uncons m1
|
||||||
Just (h, t) -> return . Just $ go h t
|
|
||||||
go p m1 = mkStream $ \_ yld sng stp ->
|
go p m1 = mkStream $ \_ yld sng stp ->
|
||||||
let single _ = sng p
|
let single _ = sng p
|
||||||
yieldk a x = yld p $ go a x
|
yieldk a x = yld p $ go a x
|
||||||
|
@ -250,6 +250,7 @@ import Control.Exception (Exception, mask_)
|
|||||||
import Control.Monad.Catch (MonadCatch)
|
import Control.Monad.Catch (MonadCatch)
|
||||||
import Control.Monad.IO.Class (MonadIO(..))
|
import Control.Monad.IO.Class (MonadIO(..))
|
||||||
import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp_)
|
import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp_)
|
||||||
|
import Data.Functor (($>))
|
||||||
import GHC.Types (SPEC(..))
|
import GHC.Types (SPEC(..))
|
||||||
import Streamly.Internal.Control.Concurrent (MonadAsync)
|
import Streamly.Internal.Control.Concurrent (MonadAsync)
|
||||||
import Streamly.Internal.Data.Fold.Type (Fold(..))
|
import Streamly.Internal.Data.Fold.Type (Fold(..))
|
||||||
@ -417,25 +418,20 @@ mapMWithInput f (Unfold ustep uinject) = Unfold step inject
|
|||||||
--
|
--
|
||||||
-- /Internal/
|
-- /Internal/
|
||||||
{-# INLINE_NORMAL either #-}
|
{-# INLINE_NORMAL either #-}
|
||||||
either :: Monad m => Unfold m a b -> Unfold m (Either a a) (Either b b)
|
either :: Applicative m => Unfold m a b -> Unfold m (Either a a) (Either b b)
|
||||||
either (Unfold step1 inject1) = Unfold step inject
|
either (Unfold step1 inject1) = Unfold step inject
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
inject (Left a) = do
|
inject (Left a) = (, Left) <$> inject1 a
|
||||||
r <- inject1 a
|
inject (Right a) = (, Right) <$> inject1 a
|
||||||
return (r, Left)
|
|
||||||
inject (Right a) = do
|
|
||||||
r <- inject1 a
|
|
||||||
return (r, Right)
|
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step (st, f) = do
|
step (st, f) = do
|
||||||
r <- step1 st
|
(\case
|
||||||
return $ case r of
|
|
||||||
Yield x s -> Yield (f x) (s, f)
|
Yield x s -> Yield (f x) (s, f)
|
||||||
Skip s -> Skip (s, f)
|
Skip s -> Skip (s, f)
|
||||||
Stop -> Stop
|
Stop -> Stop) <$> step1 st
|
||||||
|
|
||||||
-- See StreamD.scanlM' for implementing this.
|
-- See StreamD.scanlM' for implementing this.
|
||||||
--
|
--
|
||||||
@ -452,30 +448,29 @@ scanlM' = undefined
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
{-# INLINE_NORMAL fromStreamD #-}
|
{-# INLINE_NORMAL fromStreamD #-}
|
||||||
fromStreamD :: Monad m => Unfold m (Stream m a) a
|
fromStreamD :: Applicative m => Unfold m (Stream m a) a
|
||||||
fromStreamD = Unfold step return
|
fromStreamD = Unfold step pure
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step (UnStream step1 state1) = do
|
step (UnStream step1 state1) =
|
||||||
r <- step1 defState state1
|
(\case
|
||||||
return $ case r of
|
|
||||||
Yield x s -> Yield x (Stream step1 s)
|
Yield x s -> Yield x (Stream step1 s)
|
||||||
Skip s -> Skip (Stream step1 s)
|
Skip s -> Skip (Stream step1 s)
|
||||||
Stop -> Stop
|
Stop -> Stop) <$> step1 defState state1
|
||||||
|
|
||||||
{-# INLINE_NORMAL fromStreamK #-}
|
{-# INLINE_NORMAL fromStreamK #-}
|
||||||
fromStreamK :: Monad m => Unfold m (K.Stream m a) a
|
fromStreamK :: Applicative m => Unfold m (K.Stream m a) a
|
||||||
fromStreamK = Unfold step return
|
fromStreamK = Unfold step pure
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step stream = do
|
step stream = do
|
||||||
r <- K.uncons stream
|
(\case
|
||||||
return $ case r of
|
|
||||||
Just (x, xs) -> Yield x xs
|
Just (x, xs) -> Yield x xs
|
||||||
Nothing -> Stop
|
Nothing -> Stop) <$> K.uncons stream
|
||||||
|
|
||||||
-- XXX Using Unfold.fromStreamD seems to be faster (using cross product test
|
-- XXX Using Unfold.fromStreamD seems to be faster (using cross product test
|
||||||
-- case) than using fromStream even if it is implemented using fromStreamD.
|
-- case) than using fromStream even if it is implemented using fromStreamD.
|
||||||
@ -486,7 +481,7 @@ fromStreamK = Unfold step return
|
|||||||
-- /Since: 0.8.0/
|
-- /Since: 0.8.0/
|
||||||
--
|
--
|
||||||
{-# INLINE_NORMAL fromStream #-}
|
{-# INLINE_NORMAL fromStream #-}
|
||||||
fromStream :: (IsStream t, Monad m) => Unfold m (t m a) a
|
fromStream :: (IsStream t, Applicative m) => Unfold m (t m a) a
|
||||||
fromStream = lmap IsStream.toStream fromStreamK
|
fromStream = lmap IsStream.toStream fromStreamK
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -497,59 +492,61 @@ fromStream = lmap IsStream.toStream fromStreamK
|
|||||||
-- effect.
|
-- effect.
|
||||||
--
|
--
|
||||||
{-# INLINE nilM #-}
|
{-# INLINE nilM #-}
|
||||||
nilM :: Monad m => (a -> m c) -> Unfold m a b
|
nilM :: Applicative m => (a -> m c) -> Unfold m a b
|
||||||
nilM f = Unfold step return
|
nilM f = Unfold step pure
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step x = f x >> return Stop
|
step x = f x $> Stop
|
||||||
|
|
||||||
-- | Prepend a monadic single element generator function to an 'Unfold'. The
|
-- | Prepend a monadic single element generator function to an 'Unfold'. The
|
||||||
-- same seed is used in the action as well as the unfold.
|
-- same seed is used in the action as well as the unfold.
|
||||||
--
|
--
|
||||||
-- /Pre-release/
|
-- /Pre-release/
|
||||||
{-# INLINE_NORMAL consM #-}
|
{-# INLINE_NORMAL consM #-}
|
||||||
consM :: Monad m => (a -> m b) -> Unfold m a b -> Unfold m a b
|
consM :: Applicative m => (a -> m b) -> Unfold m a b -> Unfold m a b
|
||||||
consM action unf = Unfold step inject
|
consM action unf = Unfold step inject
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
inject = return . Left
|
inject = pure . Left
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step (Left a) =
|
step (Left a) = (`Yield` Right (D.unfold unf a)) <$> action a
|
||||||
action a >>= \r -> return $ Yield r (Right (D.unfold unf a))
|
|
||||||
step (Right (UnStream step1 st)) = do
|
step (Right (UnStream step1 st)) = do
|
||||||
res <- step1 defState st
|
(\case
|
||||||
case res of
|
Yield x s -> Yield x (Right (Stream step1 s))
|
||||||
Yield x s -> return $ Yield x (Right (Stream step1 s))
|
Skip s -> Skip (Right (Stream step1 s))
|
||||||
Skip s -> return $ Skip (Right (Stream step1 s))
|
Stop -> Stop) <$> step1 defState st
|
||||||
Stop -> return Stop
|
|
||||||
|
|
||||||
-- | Convert a list of pure values to a 'Stream'
|
-- | Convert a list of pure values to a 'Stream'
|
||||||
--
|
--
|
||||||
-- /Since: 0.8.0/
|
-- /Since: 0.8.0/
|
||||||
--
|
--
|
||||||
{-# INLINE_LATE fromList #-}
|
{-# INLINE_LATE fromList #-}
|
||||||
fromList :: Monad m => Unfold m [a] a
|
fromList :: Applicative m => Unfold m [a] a
|
||||||
fromList = Unfold step inject
|
fromList = Unfold step pure
|
||||||
where
|
|
||||||
inject = return
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step (x:xs) = return $ Yield x xs
|
step (x:xs) = pure $ Yield x xs
|
||||||
step [] = return Stop
|
step [] = pure Stop
|
||||||
|
|
||||||
-- | Convert a list of monadic values to a 'Stream'
|
-- | Convert a list of monadic values to a 'Stream'
|
||||||
--
|
--
|
||||||
-- /Since: 0.8.0/
|
-- /Since: 0.8.0/
|
||||||
--
|
--
|
||||||
{-# INLINE_LATE fromListM #-}
|
{-# INLINE_LATE fromListM #-}
|
||||||
fromListM :: Monad m => Unfold m [m a] a
|
fromListM :: Applicative m => Unfold m [m a] a
|
||||||
fromListM = Unfold step inject
|
fromListM = Unfold step pure
|
||||||
where
|
|
||||||
inject = return
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step (x:xs) = x >>= \r -> return $ Yield r xs
|
step (x:xs) = (`Yield` xs) <$> x
|
||||||
step [] = return Stop
|
step [] = pure Stop
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
-- Specialized Generation
|
-- Specialized Generation
|
||||||
@ -560,31 +557,31 @@ fromListM = Unfold step inject
|
|||||||
-- /Since: 0.8.0/
|
-- /Since: 0.8.0/
|
||||||
--
|
--
|
||||||
{-# INLINE replicateM #-}
|
{-# INLINE replicateM #-}
|
||||||
replicateM :: Monad m => Int -> Unfold m (m a) a
|
replicateM :: Applicative m => Int -> Unfold m (m a) a
|
||||||
replicateM n = Unfold step inject
|
replicateM n = Unfold step inject
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
inject x = return (x, n)
|
inject action = pure (action, n)
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step (x, i) =
|
step (action, i) =
|
||||||
if i <= 0
|
if i <= 0
|
||||||
then return Stop
|
then pure Stop
|
||||||
else do
|
else (\x -> Yield x (action, i - 1)) <$> action
|
||||||
x1 <- x
|
|
||||||
return $ Yield x1 (x, i - 1)
|
|
||||||
|
|
||||||
-- | Generates an infinite stream repeating the seed.
|
-- | Generates an infinite stream repeating the seed.
|
||||||
--
|
--
|
||||||
-- /Since: 0.8.0/
|
-- /Since: 0.8.0/
|
||||||
--
|
--
|
||||||
{-# INLINE repeatM #-}
|
{-# INLINE repeatM #-}
|
||||||
repeatM :: Monad m => Unfold m (m a) a
|
repeatM :: Applicative m => Unfold m (m a) a
|
||||||
repeatM = Unfold step return
|
repeatM = Unfold step pure
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step x = x >>= \x1 -> return $ Yield x1 x
|
step action = (`Yield` action) <$> action
|
||||||
|
|
||||||
-- | Generates an infinite stream starting with the given seed and applying the
|
-- | Generates an infinite stream starting with the given seed and applying the
|
||||||
-- given function repeatedly.
|
-- given function repeatedly.
|
||||||
@ -592,13 +589,13 @@ repeatM = Unfold step return
|
|||||||
-- /Since: 0.8.0/
|
-- /Since: 0.8.0/
|
||||||
--
|
--
|
||||||
{-# INLINE iterateM #-}
|
{-# INLINE iterateM #-}
|
||||||
iterateM :: Monad m => (a -> m a) -> Unfold m (m a) a
|
iterateM :: Applicative m => (a -> m a) -> Unfold m (m a) a
|
||||||
iterateM f = Unfold step id
|
iterateM f = Unfold step id
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step x = do
|
step x = Yield x <$> f x
|
||||||
fx <- f x
|
|
||||||
return $ Yield x fx
|
|
||||||
|
|
||||||
-- | @fromIndicesM gen@ generates an infinite stream of values using @gen@
|
-- | @fromIndicesM gen@ generates an infinite stream of values using @gen@
|
||||||
-- starting from the seed.
|
-- starting from the seed.
|
||||||
@ -610,13 +607,13 @@ iterateM f = Unfold step id
|
|||||||
-- /Pre-release/
|
-- /Pre-release/
|
||||||
--
|
--
|
||||||
{-# INLINE_NORMAL fromIndicesM #-}
|
{-# INLINE_NORMAL fromIndicesM #-}
|
||||||
fromIndicesM :: Monad m => (Int -> m a) -> Unfold m Int a
|
fromIndicesM :: Applicative m => (Int -> m a) -> Unfold m Int a
|
||||||
fromIndicesM gen = Unfold step return
|
fromIndicesM gen = Unfold step pure
|
||||||
where
|
|
||||||
|
where
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step i = do
|
step i = (`Yield` (i + 1)) <$> gen i
|
||||||
x <- gen i
|
|
||||||
return $ Yield x (i + 1)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Filtering
|
-- Filtering
|
||||||
@ -630,20 +627,20 @@ fromIndicesM gen = Unfold step return
|
|||||||
-- /Since: 0.8.0/
|
-- /Since: 0.8.0/
|
||||||
--
|
--
|
||||||
{-# INLINE_NORMAL take #-}
|
{-# INLINE_NORMAL take #-}
|
||||||
take :: Monad m => Int -> Unfold m a b -> Unfold m a b
|
take :: Applicative m => Int -> Unfold m a b -> Unfold m a b
|
||||||
take n (Unfold step1 inject1) = Unfold step inject
|
take n (Unfold step1 inject1) = Unfold step inject
|
||||||
where
|
|
||||||
inject x = do
|
where
|
||||||
s <- inject1 x
|
|
||||||
return (s, 0)
|
inject x = (, 0) <$> inject1 x
|
||||||
|
|
||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step (st, i) | i < n = do
|
step (st, i) | i < n = do
|
||||||
r <- step1 st
|
(\case
|
||||||
return $ case r of
|
|
||||||
Yield x s -> Yield x (s, i + 1)
|
Yield x s -> Yield x (s, i + 1)
|
||||||
Skip s -> Skip (s, i)
|
Skip s -> Skip (s, i)
|
||||||
Stop -> Stop
|
Stop -> Stop) <$> step1 st
|
||||||
step (_, _) = return Stop
|
step (_, _) = pure Stop
|
||||||
|
|
||||||
-- | Same as 'filter' but with a monadic predicate.
|
-- | Same as 'filter' but with a monadic predicate.
|
||||||
--
|
--
|
||||||
@ -676,31 +673,25 @@ filter f = filterM (return . f)
|
|||||||
-- /Since: 0.8.0/
|
-- /Since: 0.8.0/
|
||||||
--
|
--
|
||||||
{-# INLINE_NORMAL drop #-}
|
{-# INLINE_NORMAL drop #-}
|
||||||
drop :: Monad m => Int -> Unfold m a b -> Unfold m a b
|
drop :: Applicative m => Int -> Unfold m a b -> Unfold m a b
|
||||||
drop n (Unfold step inject) = Unfold step' inject'
|
drop n (Unfold step inject) = Unfold step' inject'
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
inject' a = do
|
inject' a = (, n) <$> inject a
|
||||||
b <- inject a
|
|
||||||
return (b, n)
|
|
||||||
|
|
||||||
{-# INLINE_LATE step' #-}
|
{-# INLINE_LATE step' #-}
|
||||||
step' (st, i)
|
step' (st, i)
|
||||||
| i > 0 = do
|
| i > 0 = do
|
||||||
r <- step st
|
(\case
|
||||||
return
|
Yield _ s -> Skip (s, i - 1)
|
||||||
$ case r of
|
Skip s -> Skip (s, i)
|
||||||
Yield _ s -> Skip (s, i - 1)
|
Stop -> Stop) <$> step st
|
||||||
Skip s -> Skip (s, i)
|
|
||||||
Stop -> Stop
|
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
r <- step st
|
(\case
|
||||||
return
|
Yield x s -> Yield x (s, 0)
|
||||||
$ case r of
|
Skip s -> Skip (s, 0)
|
||||||
Yield x s -> Yield x (s, 0)
|
Stop -> Stop) <$> step st
|
||||||
Skip s -> Skip (s, 0)
|
|
||||||
Stop -> Stop
|
|
||||||
|
|
||||||
-- | @dropWhileM f unf@ drops elements from the stream generated by @unf@ while
|
-- | @dropWhileM f unf@ drops elements from the stream generated by @unf@ while
|
||||||
-- the condition holds true. The condition function @f@ is /monadic/ in nature.
|
-- the condition holds true. The condition function @f@ is /monadic/ in nature.
|
||||||
@ -793,10 +784,10 @@ gbracket_ bef exc aft (Unfold estep einject) (Unfold step1 inject1) =
|
|||||||
return $ Skip (Left r)
|
return $ Skip (Left r)
|
||||||
step (Left st) = do
|
step (Left st) = do
|
||||||
res <- estep st
|
res <- estep st
|
||||||
case res of
|
return $ case res of
|
||||||
Yield x s -> return $ Yield x (Left s)
|
Yield x s -> Yield x (Left s)
|
||||||
Skip s -> return $ Skip (Left s)
|
Skip s -> Skip (Left s)
|
||||||
Stop -> return Stop
|
Stop -> Stop
|
||||||
|
|
||||||
-- | Run the alloc action @a -> m c@ with async exceptions disabled but keeping
|
-- | Run the alloc action @a -> m c@ with async exceptions disabled but keeping
|
||||||
-- blocking operations interruptible (see 'Control.Exception.mask'). Use the
|
-- blocking operations interruptible (see 'Control.Exception.mask'). Use the
|
||||||
@ -858,10 +849,10 @@ gbracket bef exc aft (Unfold estep einject) (Unfold step1 inject1) =
|
|||||||
return $ Skip (Left r)
|
return $ Skip (Left r)
|
||||||
step (Left st) = do
|
step (Left st) = do
|
||||||
res <- estep st
|
res <- estep st
|
||||||
case res of
|
return $ case res of
|
||||||
Yield x s -> return $ Yield x (Left s)
|
Yield x s -> Yield x (Left s)
|
||||||
Skip s -> return $ Skip (Left s)
|
Skip s -> Skip (Left s)
|
||||||
Stop -> return Stop
|
Stop -> Stop
|
||||||
|
|
||||||
-- | Run a side effect @a -> m c@ on the input @a@ before unfolding it using
|
-- | Run a side effect @a -> m c@ on the input @a@ before unfolding it using
|
||||||
-- @Unfold m a b@.
|
-- @Unfold m a b@.
|
||||||
@ -964,10 +955,10 @@ onException action (Unfold step1 inject1) = Unfold step inject
|
|||||||
{-# INLINE_LATE step #-}
|
{-# INLINE_LATE step #-}
|
||||||
step (st, v) = do
|
step (st, v) = do
|
||||||
res <- step1 st `MC.onException` action v
|
res <- step1 st `MC.onException` action v
|
||||||
case res of
|
return $ case res of
|
||||||
Yield x s -> return $ Yield x (s, v)
|
Yield x s -> Yield x (s, v)
|
||||||
Skip s -> return $ Skip (s, v)
|
Skip s -> Skip (s, v)
|
||||||
Stop -> return Stop
|
Stop -> Stop
|
||||||
|
|
||||||
{-# INLINE_NORMAL _finally #-}
|
{-# INLINE_NORMAL _finally #-}
|
||||||
_finally :: MonadCatch m => (a -> m c) -> Unfold m a b -> Unfold m a b
|
_finally :: MonadCatch m => (a -> m c) -> Unfold m a b -> Unfold m a b
|
||||||
|
Loading…
Reference in New Issue
Block a user