3#if __GLASGOW_HASKELL__ >= 800
4{-# OPTIONS_GHC -Wno-orphans #-}
10-- Module : Streamly.Streams.Prelude
11-- Copyright : (c) 2017 Harendra Kumar
14-- Maintainer : harendra.kumar@gmail.com
15-- Stability : experimental
19module Streamly.Streams.Prelude
21 -- * Stream Conversion
28 -- * Conversion operations
41 -- Lazy left folds are useful only for reversing the stream
50 -- * Zip style operations
65import Control.Monad.Trans (MonadTrans(..))
66import Prelude hiding (foldr)
67import qualified Prelude
69#ifdef USE_STREAMK_ONLY
70import qualified Streamly.Streams.StreamK as S
72import qualified Streamly.Streams.StreamD as S
75import Streamly.Streams.StreamK (IsStream(..))
76import qualified Streamly.Streams.StreamK as K
77import qualified Streamly.Streams.StreamD as D
79------------------------------------------------------------------------------
80-- Conversion to and from direct style stream
81------------------------------------------------------------------------------
83-- These definitions are dependent on what is imported as S
84{-# INLINE fromStreamS #-}
85fromStreamS :: (IsStream t, Monad m) => S.Stream m a -> t m a
86fromStreamS = fromStream . S.toStreamK
88{-# INLINE toStreamS #-}
89toStreamS :: (IsStream t, Monad m) => t m a -> S.Stream m a
90toStreamS = S.fromStreamK . toStream
92------------------------------------------------------------------------------
94------------------------------------------------------------------------------
96{-# INLINE_EARLY drain #-}
97drain :: (IsStream t, Monad m) => t m a -> m ()
98drain m = D.drain $ D.fromStreamK (toStream m)
99{-# RULES "drain fallback to CPS" [1]
100 forall a. D.drain (D.fromStreamK a) = K.drain a #-}
102------------------------------------------------------------------------------
104------------------------------------------------------------------------------
108-- fromList = 'Prelude.foldr' 'K.cons' 'K.nil'
111-- Construct a stream from a list of pure values. This is more efficient than
112-- 'K.fromFoldable' for serial streams.
115{-# INLINE_EARLY fromList #-}
116fromList :: (Monad m, IsStream t) => [a] -> t m a
117fromList = fromStreamS . S.fromList
118{-# RULES "fromList fallback to StreamK" [1]
119 forall a. S.toStreamK (S.fromList a) = K.fromFoldable a #-}
121-- | Convert a stream into a list in the underlying monad.
125toList :: (Monad m, IsStream t) => t m a -> m [a]
126toList m = S.toList $ toStreamS m
128------------------------------------------------------------------------------
130------------------------------------------------------------------------------
133foldrM :: (Monad m, IsStream t) => (a -> m b -> m b) -> m b -> t m a -> m b
134foldrM step acc m = S.foldrM step acc $ toStreamS m
136{-# INLINE foldrMx #-}
137foldrMx :: (Monad m, IsStream t)
138 => (a -> m x -> m x) -> m x -> (m x -> m b) -> t m a -> m b
139foldrMx step final project m = D.foldrMx step final project $ D.toStreamD m
142foldr :: (Monad m, IsStream t) => (a -> b -> b) -> b -> t m a -> m b
143foldr f z = foldrM (\a b -> b >>= return . f a) (return z)
145-- | Like 'foldlx'', but with a monadic step function.
148{-# INLINE foldlMx' #-}
149foldlMx' :: (IsStream t, Monad m)
150 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
151foldlMx' step begin done m = S.foldlMx' step begin done $ toStreamS m
153-- | Strict left fold with an extraction function. Like the standard strict
154-- left fold, but applies a user supplied extraction function (the third
155-- argument) to the folded value at the end. This is designed to work with the
156-- @foldl@ library. The suffix @x@ is a mnemonic for extraction.
159{-# INLINE foldlx' #-}
160foldlx' :: (IsStream t, Monad m)
161 => (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
162foldlx' step begin done m = S.foldlx' step begin done $ toStreamS m
164-- | Strict left associative fold.
168foldl' :: (Monad m, IsStream t) => (b -> a -> b) -> b -> t m a -> m b
169foldl' step begin m = S.foldl' step begin $ toStreamS m
172foldlS :: IsStream t => (t m b -> a -> t m b) -> t m b -> t m a -> t m b
175-- | Lazy left fold to a transformer monad.
177-- For example, to reverse a stream:
179-- > S.toList $ S.foldlT (flip S.cons) S.nil $ (S.fromList [1..5] :: SerialT IO Int)
182foldlT :: (Monad m, IsStream t, Monad (s m), MonadTrans s)
183 => (s m b -> a -> s m b) -> s m b -> t m a -> s m b
184foldlT f z s = S.foldlT f z (toStreamS s)
186------------------------------------------------------------------------------
188------------------------------------------------------------------------------
190-- postscanlM' followed by mapM
191{-# INLINE postscanlMx' #-}
192postscanlMx' :: (IsStream t, Monad m)
193 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> t m b
194postscanlMx' step begin done m =
195 D.fromStreamD $ D.postscanlMx' step begin done $ D.toStreamD m
197-- postscanl' followed by map
198{-# INLINE postscanlx' #-}
199postscanlx' :: (IsStream t, Monad m)
200 => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
201postscanlx' step begin done m =
202 D.fromStreamD $ D.postscanlx' step begin done $ D.toStreamD m
204-- scanlM' followed by mapM
206{-# INLINE scanlMx' #-}
207scanlMx' :: (IsStream t, Monad m)
208 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> t m b
209scanlMx' step begin done m =
210 D.fromStreamD $ D.scanlMx' step begin done $ D.toStreamD m
212-- scanl followed by map
214-- | Strict left scan with an extraction function. Like 'scanl'', but applies a
215-- user supplied extraction function (the third argument) at each step. This is
216-- designed to work with the @foldl@ library. The suffix @x@ is a mnemonic for
220{-# INLINE scanlx' #-}
221scanlx' :: (IsStream t, Monad m)
222 => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
223scanlx' step begin done m =
224 fromStreamS $ S.scanlx' step begin done $ toStreamS m
226------------------------------------------------------------------------------
228------------------------------------------------------------------------------
230-- | Compare two streams for equality
234eqBy :: (IsStream t, Monad m) => (a -> b -> Bool) -> t m a -> t m b -> m Bool
235eqBy f m1 m2 = D.eqBy f (D.toStreamD m1) (D.toStreamD m2)
237-- | Compare two streams
242 :: (IsStream t, Monad m)
243 => (a -> b -> Ordering) -> t m a -> t m b -> m Ordering
244cmpBy f m1 m2 = D.cmpBy f (D.toStreamD m1) (D.toStreamD m2)
246------------------------------------------------------------------------------
248------------------------------------------------------------------------------
251-- XXX do we have facilities in Foldable to fold any Foldable in this manner?
253-- | Perform a pair wise bottom up hierarchical fold of elements in the
254-- container using the given function as the merge function.
256-- This will perform a balanced merge sort if the merge function is
260{-# INLINABLE foldbWith #-}
261foldbWith :: IsStream t
262 => (t m a -> t m a -> t m a) -> SerialT Identity (t m a) -> t m a
263foldbWith f = K.foldb f K.nil
266-- | A variant of 'Data.Foldable.fold' that allows you to fold a 'Foldable'
267-- container of streams using the specified stream sum operation.
269-- @foldWith 'async' $ map return [1..3]@
272{-# INLINABLE foldWith #-}
273foldWith :: (IsStream t, Foldable f)
274 => (t m a -> t m a -> t m a) -> f (t m a) -> t m a
275foldWith f = Prelude.foldr f K.nil
277-- | A variant of 'foldMap' that allows you to map a monadic streaming action
278-- on a 'Foldable' container and then fold it using the specified stream sum
281-- @foldMapWith 'async' return [1..3]@
284{-# INLINABLE foldMapWith #-}
285foldMapWith :: (IsStream t, Foldable f)
286 => (t m b -> t m b -> t m b) -> (a -> t m b) -> f a -> t m b
287foldMapWith f g = Prelude.foldr (f . g) K.nil
289-- | Like 'foldMapWith' but with the last two arguments reversed i.e. the
290-- monadic streaming function is the last argument.
293{-# INLINABLE forEachWith #-}
294forEachWith :: (IsStream t, Foldable f)
295 => (t m b -> t m b -> t m b) -> f a -> (a -> t m b) -> t m b
296forEachWith f xs g = Prelude.foldr (f . g) K.nil xs
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list