on master help sign in
Refactor/rename/add basic unfold constructors
commit0954511144cb7cace629f7553bc965d9aa6ade4c authorHarendra Kumar <harendra@composewell.com> dateWed 24 Mar 2021, 20:29 (6 years ago) parent8af1c36
5 files changed+119−69
benchmark/Streamly/Benchmark/Data/Unfold.hs+9−9 src/Streamly/Data/Unfold.hs+5−1 src/Streamly/Internal/Data/Unfold.hs+11−24 src/Streamly/Internal/Data/Unfold/Type.hs+82−23 test/Streamly/Test/Data/Unfold.hs+12−12
benchmark/Streamly/Benchmark/Data/Unfold.hs+9−9
@@ -181,13 +181,13 @@ consM :: Monad m => Int -> Int -> m ()
181181consM size start =
182182 drainTransformationDefault (size + start) (UF.consM return) start
183183
184−{-# INLINE _singletonM #-}
185−_singletonM :: Monad m => Int -> Int -> m ()
186−_singletonM _ start = drainGeneration (UF.singletonM return) start
184+{-# INLINE _functionM #-}
185+_functionM :: Monad m => Int -> Int -> m ()
186+_functionM _ start = drainGeneration (UF.functionM return) start
187187
188−{-# INLINE _singleton #-}
189−_singleton :: Monad m => Int -> Int -> m ()
190−_singleton _ start = drainGeneration (UF.singleton id) start
188+{-# INLINE _function #-}
189+_function :: Monad m => Int -> Int -> m ()
190+_function _ start = drainGeneration (UF.function id) start
191191
192192{-# INLINE _identity #-}
193193_identity :: Monad m => Int -> Int -> m ()
@@ -626,8 +626,8 @@ o_1_space_generation size =
626626 -- Very small benchmarks, reporting in ns
627627 -- , benchIO "nilM" $ nilM size
628628 , benchIO "consM" $ consM size
629− -- , benchIO "singletonM" $ singletonM size
630− -- , benchIO "singleton" $ singleton size
629+ -- , benchIO "functionM" $ functionM size
630+ -- , benchIO "function" $ function size
631631 -- , benchIO "identity" $ identity size
632632 -- , benchIO "const" $ const size
633633 , benchIO "unfoldrM" $ unfoldrM size
@@ -736,7 +736,7 @@ inspect $ hasNoTypeClasses 'readWriteOnExceptionUnfold
736736readWriteHandleExceptionUnfold :: Handle -> Handle -> IO ()
737737readWriteHandleExceptionUnfold inh devNull =
738738 let handler (_e :: SomeException) = hClose inh >> return 10
739− readEx = UF.handle (UF.singletonM handler) FH.read
739+ readEx = UF.handle (UF.functionM handler) FH.read
740740 in SP.fold (FH.write devNull) $ SP.unfold readEx inh
741741
742742#ifdef INSPECTION
src/Streamly/Data/Unfold.hs+5−1
@@ -63,9 +63,13 @@ module Streamly.Data.Unfold
6363 -- One to one correspondence with
6464 -- "Streamly.Internal.Data.Stream.IsStream.Generate"
6565
66+ -- ** Basic Constructors
67+ , unfoldrM
68+ , function
69+ , functionM
70+
6671 -- ** Generators
6772 -- | Generate a monadic stream from a seed.
68− , unfoldrM
6973 , repeatM
7074 , replicateM
7175 , iterateM
src/Streamly/Internal/Data/Unfold.hs+11−24
@@ -85,18 +85,22 @@ module Streamly.Internal.Data.Unfold
8585 -- * Unfolds
8686 -- One to one correspondence with
8787 -- "Streamly.Internal.Data.Stream.IsStream.Generate"
88− -- ** Primitives
89− , singletonM
90− , singleton
88+ -- ** Basic Constructors
89+ , mkUnfoldM
90+ , mkUnfoldrM
91+ , unfoldrM
92+ , functionM
93+ , function
9194 , identity
92− , yieldM
93− , yield
9495 , nilM
9596 , consM
9697
98+ -- ** From Values
99+ , yieldM
100+ , yield
101+
97102 -- ** Generators
98103 -- | Generate a monadic stream from a seed.
99− , unfoldrM
100104 , repeatM
101105 , replicateM
102106 , fromIndicesM
@@ -224,7 +228,7 @@ import Prelude
224228-- | Map an action on the input argument of the 'Unfold'.
225229--
226230-- @
227−-- lmapM f = Unfold.many (Unfold.singletonM f)
231+-- lmapM f = Unfold.many (Unfold.functionM f)
228232-- @
229233--
230234-- /Pre-release/
@@ -468,23 +472,6 @@ fromListM = Unfold step inject
468472 step (x:xs) = x >>= \r -> return $ Yield r xs
469473 step [] = return Stop
470474
471−-- | Build a stream by unfolding a /monadic/ step function starting from a seed.
472−-- The step function returns the next element in the stream and the next seed
473−-- value. When it is done it returns 'Nothing' and the stream ends.
474−--
475−-- /Pre-release/
476−--
477−{-# INLINE unfoldrM #-}
478−unfoldrM :: Monad m => (a -> m (Maybe (b, a))) -> Unfold m a b
479−unfoldrM next = Unfold step return
480− where
481− {-# INLINE_LATE step #-}
482− step st = do
483− r <- next st
484− return $ case r of
485− Just (x, s) -> Yield x s
486− Nothing -> Stop
487−
488475------------------------------------------------------------------------------
489476-- Specialized Generation
490477------------------------------------------------------------------------------
src/Streamly/Internal/Data/Unfold/Type.hs+82−23
@@ -9,10 +9,15 @@
99module Streamly.Internal.Data.Unfold.Type
1010 ( Unfold (..)
1111
12− -- * From values
13− , singletonM
14− , singleton
12+ -- * Basic Constructors
13+ , mkUnfoldM
14+ , mkUnfoldrM
15+ , unfoldrM
16+ , functionM
17+ , function
1518 , identity
19+
20+ -- * From Values
1621 , yieldM
1722 , yield
1823
@@ -73,10 +78,54 @@ data Unfold m a b =
7378 -- | @Unfold step inject@
7479 forall s. Unfold (s -> m (Step s b)) (a -> m s)
7580
81+------------------------------------------------------------------------------
82+-- Basic constructors
83+------------------------------------------------------------------------------
84+
85+-- | Make an unfold from @step@ and @inject@ functions.
86+--
87+-- /Pre-release/
88+{-# INLINE mkUnfoldM #-}
89+mkUnfoldM :: (s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
90+mkUnfoldM = Unfold
91+
92+-- | Make an unfold from a step function.
93+--
94+-- See also: 'unfoldrM'
95+--
96+-- /Pre-release/
97+{-# INLINE mkUnfoldrM #-}
98+mkUnfoldrM :: Applicative m => (a -> m (Step a b)) -> Unfold m a b
99+mkUnfoldrM step = Unfold step pure
100+
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.
104+--
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.
108+--
109+-- /Pre-release/
110+--
111+{-# INLINE unfoldrM #-}
112+unfoldrM :: Applicative m => (a -> m (Maybe (b, a))) -> Unfold m a b
113+unfoldrM next = Unfold step pure
114+ where
115+ {-# INLINE_LATE step #-}
116+ step st =
117+ (\case
118+ Just (x, s) -> Yield x s
119+ Nothing -> Stop) <$> next st
120+
121+------------------------------------------------------------------------------
122+-- Map input
123+------------------------------------------------------------------------------
124+
76125-- | Map a function on the input argument of the 'Unfold'.
77126--
78127-- @
79−-- lmap f = Unfold.many (Unfold.singleton f)
128+-- lmap f = Unfold.many (Unfold.function f)
80129-- @
81130--
82131-- /Pre-release/
@@ -109,9 +158,10 @@ instance Functor m => Functor (Unfold m a) where
109158-- Applicative
110159------------------------------------------------------------------------------
111160
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
113162-- supplied monadic action.
114163--
164+-- /Pre-release/
115165{-# INLINE yieldM #-}
116166yieldM :: Applicative m => m b -> Unfold m a b
117167yieldM m = Unfold step inject
@@ -124,6 +174,10 @@ yieldM m = Unfold step inject
124174 step True = pure Stop
125175
126176-- | Discards the unfold input and always returns the argument of 'yield'.
177+--
178+-- > yield = yieldM . pure
179+--
180+-- /Pre-release/
127181yield :: Applicative m => b -> Unfold m a b
128182yield = yieldM Prelude.. pure
129183
@@ -314,36 +368,41 @@ instance Monad m => Monad (Unfold m a) where
314368-- Category
315369-------------------------------------------------------------------------------
316370
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
372+-- stream.
318373--
319−{-# INLINE singletonM #-}
320−singletonM :: Monad m => (a -> m b) -> Unfold m a b
321−singletonM f = Unfold step inject
374+-- /Pre-release/
375+{-# INLINE functionM #-}
376+functionM :: Applicative m => (a -> m b) -> Unfold m a b
377+functionM f = Unfold step inject
322378
323379 where
324380
325− inject x = return $ Just x
381+ inject x = pure $ Just x
326382
327383 {-# INLINE_LATE step #-}
328− step (Just x) = f x >>= \r -> return $ Yield r Nothing
329− step Nothing = return Stop
384+ step (Just x) = (`Yield` Nothing) <$> f x
385+ step Nothing = pure Stop
330386
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
388+-- stream.
332389--
333−-- > singleton f = singletonM $ return . f
390+-- > function f = functionM $ return . f
334391--
335−{-# INLINE singleton #-}
336−singleton :: Monad m => (a -> b) -> Unfold m a b
337−singleton f = singletonM $ return Prelude.. f
392+-- /Pre-release/
393+{-# INLINE function #-}
394+function :: Applicative m => (a -> b) -> Unfold m a b
395+function f = functionM $ pure Prelude.. f
338396
339−-- | Identity unfold. Generates a singleton stream with the seed as the only
340−-- element in the stream.
397+-- | Identity unfold. The unfold generates a singleton stream having the input
398+-- as the only element.
341399--
342−-- > identity = singleton Prelude.id
400+-- > identity = function Prelude.id
343401--
402+-- /Pre-release/
344403{-# INLINE identity #-}
345−identity :: Monad m => Unfold m a a
346−identity = singleton Prelude.id
404+identity :: Applicative m => Unfold m a a
405+identity = function Prelude.id
347406
348407{-# ANN type ConcatState Fuse #-}
349408data ConcatState s1 s2 = ConcatOuter s1 | ConcatInner s1 s2
@@ -468,7 +527,7 @@ zipWith f = zipWithM (\a b -> return (f a b))
468527{-# ANN module "HLint: ignore Use zip" #-}
469528instance Monad m => Arrow (Unfold m) where
470529 {-# INLINE arr #-}
471− arr = singleton
530+ arr = function
472531
473532 {-# INLINE (***) #-}
474533 u1 *** u2 = zipWith (,) (lmap fst u1) (lmap snd u2)
test/Streamly/Test/Data/Unfold.hs+12−12
@@ -67,37 +67,37 @@ testUnfoldD = testUnfold
6767
6868lmapM :: Bool
6969lmapM =
70− let unf = UF.lmapM (\x -> modify (+ 1) >> return x) (UF.singleton id)
70+ let unf = UF.lmapM (\x -> modify (+ 1) >> return x) (UF.function id)
7171 in testUnfoldMD unf 1 0 1 [1]
7272
7373supply :: Bool
7474supply =
75− let unf = UF.supply 1 (UF.singleton id)
75+ let unf = UF.supply 1 (UF.function id)
7676 in testUnfold unf undefined ([1] :: [Int])
7777
7878supplyFirst :: Bool
7979supplyFirst =
80− let unf = UF.supplyFirst 1 (UF.singleton id)
80+ let unf = UF.supplyFirst 1 (UF.function id)
8181 in testUnfold unf 2 ([(1, 2)] :: [(Int, Int)])
8282
8383supplySecond :: Bool
8484supplySecond =
85− let unf = UF.supplySecond 1 (UF.singleton id)
85+ let unf = UF.supplySecond 1 (UF.function id)
8686 in testUnfold unf 2 ([(2, 1)] :: [(Int, Int)])
8787
8888discardFirst :: Bool
8989discardFirst =
90− let unf = UF.discardFirst (UF.singleton id)
90+ let unf = UF.discardFirst (UF.function id)
9191 in testUnfold unf ((1, 2) :: (Int, Int)) [2]
9292
9393discardSecond :: Bool
9494discardSecond =
95− let unf = UF.discardSecond (UF.singleton id)
95+ let unf = UF.discardSecond (UF.function id)
9696 in testUnfold unf ((1, 2) :: (Int, Int)) [1]
9797
9898swap :: Bool
9999swap =
100− let unf = UF.swap (UF.singleton id)
100+ let unf = UF.swap (UF.function id)
101101 in testUnfold unf ((1, 2) :: (Int, Int)) [(2, 1)]
102102
103103-------------------------------------------------------------------------------
@@ -134,9 +134,9 @@ consM =
134134 unf = cns $ cns $ UF.nilM $ \a -> modify (+ a)
135135 in testUnfoldMD unf 1 0 3 [1, 2]
136136
137−singletonM :: Bool
138−singletonM =
139− let unf = UF.singletonM (\a -> modify (+ a) >> get)
137+functionM :: Bool
138+functionM =
139+ let unf = UF.functionM (\a -> modify (+ a) >> get)
140140 in testUnfoldMD unf 1 0 1 [1]
141141
142142const :: Bool
@@ -378,8 +378,8 @@ testGeneration =
378378 prop "fromStreamD" fromStreamD
379379 prop "nilM" nilM
380380 prop "consM" consM
381− prop "singletonM" singletonM
382− -- prop "singleton" singleton
381+ prop "functionM" functionM
382+ -- prop "function" function
383383 -- prop "identity" identity
384384 prop "const" const
385385 prop "unfoldrM" unfoldrM