@@ -9,10 +9,15 @@
9module Streamly.Internal.Data.Unfold.Type
9module Streamly.Internal.Data.Unfold.Type
10 ( Unfold (..)
10 ( Unfold (..)
12− -- * From values
12+ -- * Basic Constructors
13− , singletonM
13+ , mkUnfoldM
14− , singleton
14+ , mkUnfoldrM
15 , identity
18 , identity
@@ -73,10 +78,54 @@ data Unfold m a b =
73 -- | @Unfold step inject@
78 -- | @Unfold step inject@
74 forall s. Unfold (s -> m (Step s b)) (a -> m s)
79 forall s. Unfold (s -> m (Step s b)) (a -> m s)
81+------------------------------------------------------------------------------
83+------------------------------------------------------------------------------
85+-- | Make an unfold from @step@ and @inject@ functions.
88+{-# INLINE mkUnfoldM #-}
89+mkUnfoldM :: (s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
92+-- | Make an unfold from a step function.
94+-- See also: 'unfoldrM'
97+{-# INLINE mkUnfoldrM #-}
98+mkUnfoldrM :: Applicative m => (a -> m (Step a b)) -> Unfold m a b
99+mkUnfoldrM step = Unfold step pure
101+-- The type 'Step' is isomorphic to 'Maybe'. Ideally unfoldrM should be the
102+-- same as mkUnfoldrM, this is for compatibility with traditional Maybe based
103+-- unfold step functions.
105+-- | Build a stream by unfolding a /monadic/ step function starting from a seed.
106+-- The step function returns the next element in the stream and the next seed
107+-- value. When it is done it returns 'Nothing' and the stream ends.
111+{-# INLINE unfoldrM #-}
112+unfoldrM :: Applicative m => (a -> m (Maybe (b, a))) -> Unfold m a b
113+unfoldrM next = Unfold step pure
115+ {-# INLINE_LATE step #-}
118+ Just (x, s) -> Yield x s
119+ Nothing -> Stop) <$> next st
121+------------------------------------------------------------------------------
123+------------------------------------------------------------------------------
76-- | Map a function on the input argument of the 'Unfold'.
125-- | Map a function on the input argument of the 'Unfold'.
79−-- lmap f = Unfold.many (Unfold.singleton f)
128+-- lmap f = Unfold.many (Unfold.function f)
82-- /Pre-release/
131-- /Pre-release/
@@ -109,9 +158,10 @@ instance Functor m => Functor (Unfold m a) where
109-- Applicative
158-- Applicative
110------------------------------------------------------------------------------
159------------------------------------------------------------------------------
112−-- | The unfold discards its input and generates a singleton stream using the
161+-- | The unfold discards its input and generates a function stream using the
113-- supplied monadic action.
162-- supplied monadic action.
115{-# INLINE yieldM #-}
165{-# INLINE yieldM #-}
116yieldM :: Applicative m => m b -> Unfold m a b
166yieldM :: Applicative m => m b -> Unfold m a b
117yieldM m = Unfold step inject
167yieldM m = Unfold step inject
@@ -124,6 +174,10 @@ yieldM m = Unfold step inject
124 step True = pure Stop
174 step True = pure Stop
126-- | Discards the unfold input and always returns the argument of 'yield'.
176-- | Discards the unfold input and always returns the argument of 'yield'.
178+-- > yield = yieldM . pure
127yield :: Applicative m => b -> Unfold m a b
181yield :: Applicative m => b -> Unfold m a b
128yield = yieldM Prelude.. pure
182yield = yieldM Prelude.. pure
@@ -314,36 +368,41 @@ instance Monad m => Monad (Unfold m a) where
314-- Category
368-- Category
315-------------------------------------------------------------------------------
369-------------------------------------------------------------------------------
317−-- | Lift a monadic function into an unfold generating a singleton stream.
371+-- | Lift a monadic function into an unfold. The unfold generates a singleton
319−{-# INLINE singletonM #-}
374+-- /Pre-release/
375+{-# INLINE functionM #-}
320−singletonM :: Monad m => (a -> m b) -> Unfold m a b
376+functionM :: Applicative m => (a -> m b) -> Unfold m a b
321−singletonM f = Unfold step inject
377+functionM f = Unfold step inject
325− inject x = return $ Just x
381+ inject x = pure $ Just x
327 {-# INLINE_LATE step #-}
383 {-# INLINE_LATE step #-}
328− step (Just x) = f x >>= \r -> return $ Yield r Nothing
384+ step (Just x) = (`Yield` Nothing) <$> f x
329− step Nothing = return Stop
385+ step Nothing = pure Stop
331−-- | Lift a pure function into an unfold generating a singleton stream.
387+-- | Lift a pure function into an unfold. The unfold generates a singleton
333−-- > singleton f = singletonM $ return . f
390+-- > function f = functionM $ return . f
335−{-# INLINE singleton #-}
393+{-# INLINE function #-}
336−singleton :: Monad m => (a -> b) -> Unfold m a b
394+function :: Applicative m => (a -> b) -> Unfold m a b
337−singleton f = singletonM $ return Prelude.. f
395+function f = functionM $ pure Prelude.. f
339−-- | Identity unfold. Generates a singleton stream with the seed as the only
397+-- | Identity unfold. The unfold generates a singleton stream having the input
340−-- element in the stream.
398+-- as the only element.
342−-- > identity = singleton Prelude.id
400+-- > identity = function Prelude.id
344{-# INLINE identity #-}
403{-# INLINE identity #-}
345−identity :: Monad m => Unfold m a a
404+identity :: Applicative m => Unfold m a a
346−identity = singleton Prelude.id
405+identity = function Prelude.id
348{-# ANN type ConcatState Fuse #-}
407{-# ANN type ConcatState Fuse #-}
349data ConcatState s1 s2 = ConcatOuter s1 | ConcatInner s1 s2
408data ConcatState s1 s2 = ConcatOuter s1 | ConcatInner s1 s2
@@ -468,7 +527,7 @@ zipWith f = zipWithM (\a b -> return (f a b))
468{-# ANN module "HLint: ignore Use zip" #-}
527{-# ANN module "HLint: ignore Use zip" #-}
469instance Monad m => Arrow (Unfold m) where
528instance Monad m => Arrow (Unfold m) where
470 {-# INLINE arr #-}
529 {-# INLINE arr #-}
471− arr = singleton
530+ arr = function
473 {-# INLINE (***) #-}
532 {-# INLINE (***) #-}
474 u1 *** u2 = zipWith (,) (lmap fst u1) (lmap snd u2)
533 u1 *** u2 = zipWith (,) (lmap fst u1) (lmap snd u2)