on cbccb77 help sign in
161 lines 4.8 kB history raw
1{-# LANGUAGE UndecidableInstances #-}
2{-# OPTIONS_GHC -Wno-orphans #-}
4-- |
5-- Module : Streamly.Internal.Data.Stream.Common
6-- Copyright : (c) 2017 Composewell Technologies
7-- License : BSD-3-Clause
8-- Maintainer : streamly@composewell.com
9-- Stability : experimental
10-- Portability : GHC
11--
12-- Low level functions using StreamK as the intermediate stream type. These
13-- functions are used in other stream modules to implement their instances.
14--
15module Streamly.Internal.Data.Stream.Common
16 (
17 -- * Running Effects
18 drain
20 -- * Conversion operations
21 , fromList
22 , toList
24 -- * Fold operations
25 , foldrM
26 , foldrMx
27 , foldr
29 , foldlx'
30 , foldlMx'
31 , foldl'
32 , fold
34 -- * Zip style operations
35 , eqBy
36 , cmpBy
37 )
38where
40#include "inline.hs"
42import Streamly.Internal.Data.Fold.Type (Fold (..))
44#ifdef USE_STREAMK_ONLY
45import qualified Streamly.Internal.Data.Stream.StreamK as S
46import qualified Streamly.Internal.Data.Stream.StreamK.Type as S
47#else
48import qualified Streamly.Internal.Data.Stream.StreamD.Type as S
49#endif
51import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
52import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
54import Prelude hiding (foldr, repeat)
56------------------------------------------------------------------------------
57-- Conversions
58------------------------------------------------------------------------------
60{-# INLINE_EARLY drain #-}
61drain :: Monad m => K.Stream m a -> m ()
62drain m = D.drain $ D.fromStreamK m
63{-# RULES "drain fallback to CPS" [1]
64 forall a. D.drain (D.fromStreamK a) = K.drain a #-}
66------------------------------------------------------------------------------
67-- Conversions
68------------------------------------------------------------------------------
70-- |
71-- @
72-- fromList = 'Prelude.foldr' 'K.cons' 'K.nil'
73-- @
74--
75-- Construct a stream from a list of pure values. This is more efficient than
76-- 'K.fromFoldable' for serial streams.
77--
78-- @since 0.4.0
79{-# INLINE_EARLY fromList #-}
80fromList :: Monad m => [a] -> K.Stream m a
81fromList = S.toStreamK . S.fromList
82{-# RULES "fromList fallback to StreamK" [1]
83 forall a. S.toStreamK (S.fromList a) = K.fromFoldable a #-}
85-- | Convert a stream into a list in the underlying monad.
86--
87-- @since 0.1.0
88{-# INLINE toList #-}
89toList :: Monad m => K.Stream m a -> m [a]
90toList m = S.toList $ S.fromStreamK m
92------------------------------------------------------------------------------
93-- Folds
94------------------------------------------------------------------------------
96{-# INLINE foldrM #-}
97foldrM :: Monad m => (a -> m b -> m b) -> m b -> K.Stream m a -> m b
98foldrM step acc m = S.foldrM step acc $ S.fromStreamK m
100{-# INLINE foldrMx #-}
101foldrMx :: Monad m
102 => (a -> m x -> m x) -> m x -> (m x -> m b) -> K.Stream m a -> m b
103foldrMx step final project m = D.foldrMx step final project $ D.fromStreamK m
105{-# INLINE foldr #-}
106foldr :: Monad m => (a -> b -> b) -> b -> K.Stream m a -> m b
107foldr f z = foldrM (\a b -> f a <$> b) (return z)
109-- | Like 'foldlx'', but with a monadic step function.
110--
111-- @since 0.7.0
112{-# INLINE foldlMx' #-}
113foldlMx' ::
114 Monad m
115 => (x -> a -> m x) -> m x -> (x -> m b) -> K.Stream m a -> m b
116foldlMx' step begin done m = S.foldlMx' step begin done $ S.fromStreamK m
118-- | Strict left fold with an extraction function. Like the standard strict
119-- left fold, but applies a user supplied extraction function (the third
120-- argument) to the folded value at the end. This is designed to work with the
121-- @foldl@ library. The suffix @x@ is a mnemonic for extraction.
122--
123-- @since 0.7.0
124{-# INLINE foldlx' #-}
125foldlx' ::
126 Monad m => (x -> a -> x) -> x -> (x -> b) -> K.Stream m a -> m b
127foldlx' step begin done m = S.foldlx' step begin done $ S.fromStreamK m
129-- | Strict left associative fold.
130--
131-- @since 0.2.0
132{-# INLINE foldl' #-}
133foldl' ::
134 Monad m => (b -> a -> b) -> b -> K.Stream m a -> m b
135foldl' step begin m = S.foldl' step begin $ S.fromStreamK m
138{-# INLINE fold #-}
139fold :: Monad m => Fold m a b -> K.Stream m a -> m b
140fold fld m = S.fold fld $ S.fromStreamK m
142------------------------------------------------------------------------------
143-- Comparison
144------------------------------------------------------------------------------
146-- | Compare two streams for equality
147--
148-- @since 0.5.3
149{-# INLINE eqBy #-}
150eqBy :: Monad m =>
151 (a -> b -> Bool) -> K.Stream m a -> K.Stream m b -> m Bool
152eqBy f m1 m2 = D.eqBy f (D.fromStreamK m1) (D.fromStreamK m2)
154-- | Compare two streams
155--
156-- @since 0.5.3
157{-# INLINE cmpBy #-}
158cmpBy
159 :: Monad m
160 => (a -> b -> Ordering) -> K.Stream m a -> K.Stream m b -> m Ordering
161cmpBy f m1 m2 = D.cmpBy f (D.fromStreamK m1) (D.fromStreamK m2)