mirror of
https://github.com/ilyakooo0/streamly.git
synced 2024-09-19 04:37:33 +03:00
Use monadic seed in monadic scanning combinators.
- The following functions are updated: scanlM, scanlM', postscanlM, postscanlM', prescanlM'. - Update Changelog.md.
This commit is contained in:
parent
345fa5d5de
commit
8061c97a76
@ -11,6 +11,8 @@
|
||||
* Deprecate `Streamly.Data.Unicode.Stream` in favor of `Streamly.Unicode.Stream`
|
||||
* Change the signature of `foldlM'` to make the initial value of the
|
||||
accumulator monadic.
|
||||
* Change the signature of `scanlM'`, `postscanlM'` to make the initial value of
|
||||
the accumulator monadic.
|
||||
* Change the signature of `concatMapWith` to ensure that it can be
|
||||
used with a wide variety of combining functions.
|
||||
* Exception handling functions `bracket`, `handle`, `finally` now
|
||||
|
@ -861,7 +861,7 @@ scan n = composeN n $ S.scanl' (+) 0
|
||||
|
||||
{-# INLINE scanlM' #-}
|
||||
scanlM' :: MonadIO m => Int -> SerialT m Int -> m ()
|
||||
scanlM' n = composeN n $ S.scanlM' (\b a -> return $ b + a) 0
|
||||
scanlM' n = composeN n $ S.scanlM' (\b a -> return $ b + a) (return 0)
|
||||
|
||||
{-# INLINE scanl1' #-}
|
||||
scanl1' :: MonadIO m => Int -> SerialT m Int -> m ()
|
||||
@ -873,7 +873,7 @@ postscanl' n = composeN n $ S.postscanl' (+) 0
|
||||
|
||||
{-# INLINE postscanlM' #-}
|
||||
postscanlM' :: MonadIO m => Int -> SerialT m Int -> m ()
|
||||
postscanlM' n = composeN n $ S.postscanlM' (\b a -> return $ b + a) 0
|
||||
postscanlM' n = composeN n $ S.postscanlM' (\b a -> return $ b + a) (return 0)
|
||||
|
||||
{-# INLINE sequence #-}
|
||||
sequence ::
|
||||
@ -983,7 +983,7 @@ sieveScan =
|
||||
let ps = takeWhile (\p -> p * p <= n) primes
|
||||
in if P.all (\p -> n `mod` p /= 0) ps
|
||||
then (primes ++ [n], Just n)
|
||||
else (primes, Nothing)) ([2], Just 2)
|
||||
else (primes, Nothing)) (return ([2], Just 2))
|
||||
|
||||
o_n_space_mapping :: Int -> [Benchmark]
|
||||
o_n_space_mapping value =
|
||||
|
@ -2201,11 +2201,13 @@ scanx = P.scanlx'
|
||||
-- complexity when iterated over a stream. We should use StreamK style scanlM'
|
||||
-- for linear performance on iteration.
|
||||
--
|
||||
-- | Like 'scanl'' but with a monadic fold function.
|
||||
-- | Like 'scanl'' but with a monadic step function and a monadic seed.
|
||||
--
|
||||
-- @since 0.4.0
|
||||
-- /Since: 0.4.0/
|
||||
--
|
||||
-- /Since: 0.8.0 (signature change)/
|
||||
{-# INLINE scanlM' #-}
|
||||
scanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> t m b
|
||||
scanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> m b -> t m a -> t m b
|
||||
scanlM' step begin m = fromStreamD $ D.scanlM' step begin $ toStreamD m
|
||||
|
||||
-- | @scanlMAfter' accumulate initial done stream@ is like 'scanlM'' except
|
||||
@ -2290,11 +2292,13 @@ postscanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
|
||||
postscanl' step z m = fromStreamD $ D.postscanl' step z $ toStreamD m
|
||||
|
||||
-- XXX this needs to be concurrent
|
||||
-- | Like 'postscanl'' but with a monadic step function.
|
||||
-- | Like 'postscanl'' but with a monadic step function and a monadic seed.
|
||||
--
|
||||
-- @since 0.7.0
|
||||
-- /Since: 0.7.0/
|
||||
--
|
||||
-- /Since: 0.8.0 (signature change)/
|
||||
{-# INLINE postscanlM' #-}
|
||||
postscanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> t m b
|
||||
postscanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> m b -> t m a -> t m b
|
||||
postscanlM' step z m = fromStreamD $ D.postscanlM' step z $ toStreamD m
|
||||
|
||||
-- XXX prescanl does not sound very useful, enable only if there is a
|
||||
@ -2308,7 +2312,7 @@ prescanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
|
||||
prescanl' step z m = fromStreamD $ D.prescanl' step z $ toStreamD m
|
||||
|
||||
-- XXX this needs to be concurrent
|
||||
-- | Like postscanl' but with a monadic step function.
|
||||
-- | Like prescanl' but with a monadic step function and a monadic seed.
|
||||
--
|
||||
-- /Internal/
|
||||
{-# INLINE prescanlM' #-}
|
||||
@ -2605,7 +2609,7 @@ smapM step initial stream =
|
||||
-- stream
|
||||
let r = concatMap
|
||||
(\s0 ->
|
||||
postscanlM' (\(s, _) a -> step s a) (s0, undefined) stream
|
||||
postscanlM' (\(s, _) a -> step s a) (return (s0, undefined)) stream
|
||||
)
|
||||
(yieldM initial)
|
||||
in Serial.map snd r
|
||||
|
@ -3616,23 +3616,27 @@ scanlx' fstep begin done s =
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
{-# INLINE_NORMAL postscanlM' #-}
|
||||
postscanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
|
||||
postscanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
|
||||
postscanlM' fstep begin (Stream step state) =
|
||||
begin `seq` Stream step' (state, begin)
|
||||
Stream step' Nothing
|
||||
where
|
||||
{-# INLINE_LATE step' #-}
|
||||
step' gst (st, acc) = acc `seq` do
|
||||
step' _ Nothing = do
|
||||
!x <- begin
|
||||
return $ Skip (Just (state, x))
|
||||
|
||||
step' gst (Just (st, acc)) = do
|
||||
r <- step (adaptState gst) st
|
||||
case r of
|
||||
Yield x s -> do
|
||||
y <- fstep acc x
|
||||
y `seq` return (Yield y (s, y))
|
||||
Skip s -> return $ Skip (s, acc)
|
||||
!y <- fstep acc x
|
||||
return $ Yield y (Just (s, y))
|
||||
Skip s -> return $ Skip (Just (s, acc))
|
||||
Stop -> return Stop
|
||||
|
||||
{-# INLINE_NORMAL postscanl' #-}
|
||||
postscanl' :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
|
||||
postscanl' f = postscanlM' (\a b -> return (f a b))
|
||||
postscanl' f seed = postscanlM' (\a b -> return (f a b)) (return seed)
|
||||
|
||||
-- We can possibly have the "done" function as a Maybe to provide an option to
|
||||
-- emit or not emit the accumulator when the stream stops.
|
||||
@ -3660,26 +3664,43 @@ postscanlMAfter' fstep initial done (Stream step1 state1) = do
|
||||
step _ Nothing = return Stop
|
||||
|
||||
{-# INLINE_NORMAL postscanlM #-}
|
||||
postscanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
|
||||
postscanlM fstep begin (Stream step state) = Stream step' (state, begin)
|
||||
postscanlM :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
|
||||
postscanlM fstep begin (Stream step state) = Stream step' Nothing
|
||||
where
|
||||
{-# INLINE_LATE step' #-}
|
||||
step' gst (st, acc) = do
|
||||
step' _ Nothing = do
|
||||
r <- begin
|
||||
return $ Skip (Just (state, r))
|
||||
|
||||
step' gst (Just (st, acc)) = do
|
||||
r <- step (adaptState gst) st
|
||||
case r of
|
||||
Yield x s -> do
|
||||
y <- fstep acc x
|
||||
return (Yield y (s, y))
|
||||
Skip s -> return $ Skip (s, acc)
|
||||
return (Yield y (Just (s, y)))
|
||||
Skip s -> return $ Skip (Just (s, acc))
|
||||
Stop -> return Stop
|
||||
|
||||
{-# INLINE_NORMAL postscanl #-}
|
||||
postscanl :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
|
||||
postscanl f = postscanlM (\a b -> return (f a b))
|
||||
postscanl f seed = postscanlM (\a b -> return (f a b)) (return seed)
|
||||
|
||||
{-# INLINE_NORMAL scanlM' #-}
|
||||
scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
|
||||
scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
|
||||
scanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
|
||||
scanlM' fstep begin (Stream step state) = Stream step' Nothing
|
||||
where
|
||||
{-# INLINE_LATE step' #-}
|
||||
step' _ Nothing = do
|
||||
!x <- begin
|
||||
return $ Yield x (Just (state, x))
|
||||
step' gst (Just (st, acc)) = do
|
||||
r <- step (adaptState gst) st
|
||||
case r of
|
||||
Yield x s -> do
|
||||
!y <- fstep acc x
|
||||
return $ Yield y (Just (s, y))
|
||||
Skip s -> return $ Skip (Just (s, acc))
|
||||
Stop -> return Stop
|
||||
|
||||
{-# INLINE scanlMAfter' #-}
|
||||
scanlMAfter' :: Monad m
|
||||
@ -3690,15 +3711,28 @@ scanlMAfter' fstep initial done s =
|
||||
|
||||
{-# INLINE scanl' #-}
|
||||
scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
|
||||
scanl' f = scanlM' (\a b -> return (f a b))
|
||||
scanl' f seed = scanlM' (\a b -> return (f a b)) (return seed)
|
||||
|
||||
{-# INLINE_NORMAL scanlM #-}
|
||||
scanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
|
||||
scanlM fstep begin s = begin `cons` postscanlM fstep begin s
|
||||
scanlM :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
|
||||
scanlM fstep begin (Stream step state) = Stream step' Nothing
|
||||
where
|
||||
{-# INLINE_LATE step' #-}
|
||||
step' _ Nothing = do
|
||||
x <- begin
|
||||
return $ Yield x (Just (state, x))
|
||||
step' gst (Just (st, acc)) = do
|
||||
r <- step (adaptState gst) st
|
||||
case r of
|
||||
Yield x s -> do
|
||||
y <- fstep acc x
|
||||
return $ Yield y (Just (s, y))
|
||||
Skip s -> return $ Skip (Just (s, acc))
|
||||
Stop -> return $ Stop
|
||||
|
||||
{-# INLINE scanl #-}
|
||||
scanl :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
|
||||
scanl f = scanlM (\a b -> return (f a b))
|
||||
scanl f seed = scanlM (\a b -> return (f a b)) (return seed)
|
||||
|
||||
{-# INLINE_NORMAL scanl1M #-}
|
||||
scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
|
||||
|
@ -926,7 +926,7 @@ transformCombineOpsCommon constr desc eq t = do
|
||||
prop (desc <> " scanl'") $ transform (scanl' (flip const) 0) t
|
||||
(S.scanl' (flip const) 0)
|
||||
prop (desc <> " scanlM'") $ transform (scanl' (flip const) 0) t
|
||||
(S.scanlM' (\_ a -> return a) 0)
|
||||
(S.scanlM' (\_ a -> return a) (return 0))
|
||||
prop (desc <> " scanl") $ transform (scanl' (flip const) 0) t
|
||||
(S.scanl' (flip const) 0)
|
||||
prop (desc <> " scanl1'") $ transform (scanl1 (flip const)) t
|
||||
|
@ -114,7 +114,7 @@ foldlM'StrictCheck :: IORef Int -> SerialT IO Int -> IO ()
|
||||
foldlM'StrictCheck ref = S.foldlM' (\_ _ -> writeIORef ref 1) (return ())
|
||||
|
||||
scanlM'StrictCheck :: IORef Int -> SerialT IO Int -> SerialT IO ()
|
||||
scanlM'StrictCheck ref = S.scanlM' (\_ _ -> writeIORef ref 1) ()
|
||||
scanlM'StrictCheck ref = S.scanlM' (\_ _ -> writeIORef ref 1) (return ())
|
||||
|
||||
checkScanlMStrictness :: (IORef Int -> SerialT IO Int -> SerialT IO ()) -> IO ()
|
||||
checkScanlMStrictness f = do
|
||||
|
Loading…
Reference in New Issue
Block a user