on master help sign in
Add unfoldManyEither combinator
064ac66Harendra Kumar
src/Streamly/Internal/Data/Stream/IsStream/Expand.hs+2−2
@@ -379,13 +379,13 @@ mergeBy f m1 m2 = fromStreamS $ S.mergeBy f (toStreamS m1) (toStreamS m2)
379--
379--
380-- @
380-- @
381-- >>> :{
381-- >>> :{
382−-- do
382+-- do
383-- let proportionately m n = do
383-- let proportionately m n = do
384-- ref <- newIORef $ cycle $ Prelude.concat [Prelude.replicate m LT, Prelude.replicate n GT]
384-- ref <- newIORef $ cycle $ Prelude.concat [Prelude.replicate m LT, Prelude.replicate n GT]
385-- return $ \_ _ -> do
385-- return $ \_ _ -> do
386-- r <- readIORef ref
386-- r <- readIORef ref
387-- writeIORef ref $ Prelude.tail r
387-- writeIORef ref $ Prelude.tail r
388−-- return $ Prelude.head r
388+-- return $ Prelude.head r
389-- f <- proportionately 2 1
389-- f <- proportionately 2 1
390-- xs <- Stream.toList $ Stream.mergeByM f (Stream.fromList [1,1,1,1,1,1]) (Stream.fromList [2,2,2])
390-- xs <- Stream.toList $ Stream.mergeByM f (Stream.fromList [1,1,1,1,1,1]) (Stream.fromList [2,2,2])
391-- print xs
391-- print xs
src/Streamly/Internal/Data/Unfold.hs+34−1
@@ -183,6 +183,9 @@ module Streamly.Internal.Data.Unfold
183 , mapM
183 , mapM
184 , mapMWithInput
184 , mapMWithInput
185
185
186+ -- ** Either Wrapped Input
187+ , either
188+
186 -- ** Filtering
189 -- ** Filtering
187 , takeWhileM
190 , takeWhileM
188 , takeWhile
191 , takeWhile
@@ -254,7 +257,7 @@ import Streamly.Internal.Data.SVar
254import Streamly.Internal.Data.Unfold.Type
257import Streamly.Internal.Data.Unfold.Type
255import Prelude
258import Prelude
256 hiding (map, mapM, takeWhile, take, filter, const, zipWith
259 hiding (map, mapM, takeWhile, take, filter, const, zipWith
257− , drop, dropWhile)
260+ , drop, dropWhile, either)
258
261
259-- $setup
262-- $setup
260-- >>> import qualified Streamly.Data.Fold as Fold
263-- >>> import qualified Streamly.Data.Fold as Fold
@@ -424,6 +427,36 @@ mapMWithInput f (Unfold ustep uinject) = Unfold step inject
424 Skip s -> return $ Skip (inp, s)
427 Skip s -> return $ Skip (inp, s)
425 Stop -> return Stop
428 Stop -> return Stop
426
429
430+
431+-------------------------------------------------------------------------------
432+-- Either
433+-------------------------------------------------------------------------------
434+
435+-- | Make an unfold operate on values wrapped in an @Either a a@ type. 'Right
436+-- a' translates to 'Right b' and 'Left a' translates to 'Left b'.
437+--
438+-- /Internal/
439+{-# INLINE_NORMAL either #-}
440+either :: Monad m => Unfold m a b -> Unfold m (Either a a) (Either b b)
441+either (Unfold step1 inject1) = Unfold step inject
442+
443+ where
444+
445+ inject (Left a) = do
446+ r <- inject1 a
447+ return (r, Left)
448+ inject (Right a) = do
449+ r <- inject1 a
450+ return (r, Right)
451+
452+ {-# INLINE_LATE step #-}
453+ step (st, f) = do
454+ r <- step1 st
455+ return $ case r of
456+ Yield x s -> Yield (f x) (s, f)
457+ Skip s -> Skip (s, f)
458+ Stop -> Stop
459+
427-------------------------------------------------------------------------------
460-------------------------------------------------------------------------------
428-- Convert streams into unfolds
461-- Convert streams into unfolds
429-------------------------------------------------------------------------------
462-------------------------------------------------------------------------------