on master help sign in
Fix foldable/traversable instances
11d8d6dHarendra Kumar
benchmark/Linear.hs+12−1
@@ -44,6 +44,13 @@ benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
44benchPureSink :: NFData b => String -> (SerialT Identity Int -> b) -> Benchmark
44benchPureSink :: NFData b => String -> (SerialT Identity Int -> b) -> Benchmark
45benchPureSink name f = benchPure name Ops.sourceUnfoldr f
45benchPureSink name f = benchPure name Ops.sourceUnfoldr f
46
46
47+{-# INLINE benchPureSinkIO #-}
48+benchPureSinkIO
49+ :: NFData b
50+ => String -> (SerialT Identity Int -> IO b) -> Benchmark
51+benchPureSinkIO name f =
52+ bench name $ nfIO $ randomRIO (1, 1) >>= f . Ops.sourceUnfoldr
53+
47{-# INLINE benchPureSrc #-}
54{-# INLINE benchPureSrc #-}
48benchPureSrc :: String -> (Int -> SerialT Identity a) -> Benchmark
55benchPureSrc :: String -> (Int -> SerialT Identity a) -> Benchmark
49benchPureSrc name src = benchPure name src (runIdentity . runStream)
56benchPureSrc name src = benchPure name src (runIdentity . runStream)
@@ -53,7 +60,8 @@ main =
53 defaultMain
60 defaultMain
54 [ bgroup "serially"
61 [ bgroup "serially"
55 [ bgroup "pure"
62 [ bgroup "pure"
56− [ benchPureSink "eqBy" Ops.eqBy
63+ [ benchPureSink "id" id
64+ , benchPureSink "eqBy" Ops.eqBy
57 , benchPureSink "==" Ops.eqInstance
65 , benchPureSink "==" Ops.eqInstance
58 , benchPureSink "/=" Ops.eqInstanceNotEq
66 , benchPureSink "/=" Ops.eqInstanceNotEq
59 , benchPureSink "cmpBy" Ops.cmpBy
67 , benchPureSink "cmpBy" Ops.cmpBy
@@ -67,6 +75,9 @@ main =
67 , benchPureSink "showsPrec" Ops.showInstance
75 , benchPureSink "showsPrec" Ops.showInstance
68 , benchPure "showsPrecList" (\n -> S.fromList [1..n :: Int])
76 , benchPure "showsPrecList" (\n -> S.fromList [1..n :: Int])
69 Ops.showInstanceList
77 Ops.showInstanceList
78+ , benchPureSink "foldable-foldl'" Ops.foldableFoldl'
79+ , benchPureSink "foldable-sum" Ops.foldableSum
80+ , benchPureSinkIO "traversable-mapM" Ops.traversableMapM
70 ]
81 ]
71 , bgroup "generation"
82 , bgroup "generation"
72 [ -- Most basic, barely stream continuations running
83 [ -- Most basic, barely stream continuations running
benchmark/LinearOps.hs+14−1
@@ -17,8 +17,9 @@ import Data.Maybe (fromJust)
17import Prelude
17import Prelude
18 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=), (==), (<=),
18 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=), (==), (<=),
19 subtract, undefined, Maybe(..), odd, Bool, not, (>>=), mapM_, curry,
19 subtract, undefined, Maybe(..), odd, Bool, not, (>>=), mapM_, curry,
20− maxBound, div)
20+ maxBound, div, IO)
21import qualified Prelude as P
21import qualified Prelude as P
22+import qualified Data.Foldable as F
22import qualified GHC.Exts as GHC
23import qualified GHC.Exts as GHC
23
24
24import qualified Streamly as S
25import qualified Streamly as S
@@ -451,3 +452,15 @@ readInstance src =
451 in case r of
452 in case r of
452 [(x,"")] -> src S.<> x
453 [(x,"")] -> src S.<> x
453 _ -> P.error "readInstance: no parse"
454 _ -> P.error "readInstance: no parse"
455+
456+{-# INLINE foldableFoldl' #-}
457+foldableFoldl' :: Stream Identity Int -> Int
458+foldableFoldl' = F.foldl' (+) 0
459+
460+{-# INLINE foldableSum #-}
461+foldableSum :: Stream Identity Int -> Int
462+foldableSum = P.sum
463+
464+{-# INLINE traversableMapM #-}
465+traversableMapM :: Stream Identity Int -> IO (Stream Identity Int)
466+traversableMapM = P.mapM return
src/Streamly/Prelude.hs+2−4
@@ -508,7 +508,7 @@ fromHandle h = fromStream go
508-- @since 0.2.0
508-- @since 0.2.0
509{-# INLINE foldrM #-}
509{-# INLINE foldrM #-}
510foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
510foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
511−foldrM step acc m = S.foldrM step acc $ toStreamS m
511+foldrM = P.foldrM
512
512
513-- | Lazy right associative fold. For example, to fold a stream into a list:
513-- | Lazy right associative fold. For example, to fold a stream into a list:
514--
514--
@@ -520,9 +520,7 @@ foldrM step acc m = S.foldrM step acc $ toStreamS m
520-- @since 0.1.0
520-- @since 0.1.0
521{-# INLINE foldr #-}
521{-# INLINE foldr #-}
522foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
522foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
523−-- XXX somehow this definition does not perform well, need to investigate
523+foldr = P.foldr
524−-- foldr step acc m = S.foldr step acc $ S.fromStreamK (toStream m)
525−foldr f = foldrM (\a b -> return (f a b))
526
524
527-- | Right fold, for non-empty streams, using first element as the starting
525-- | Right fold, for non-empty streams, using first element as the starting
528-- value. Returns 'Nothing' if the stream is empty.
526-- value. Returns 'Nothing' if the stream is empty.
src/Streamly/Streams/Ahead.hs+1−2
@@ -1,6 +1,5 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE ConstraintKinds #-}
3−{-# LANGUAGE DeriveTraversable #-}
4{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving#-}
5{-# LANGUAGE GeneralizedNewtypeDeriving#-}
@@ -620,7 +619,7 @@ consMAhead m r = K.yieldM m `aheadS` r
620--
619--
621-- @since 0.3.0
620-- @since 0.3.0
622newtype AheadT m a = AheadT {getAheadT :: Stream m a}
621newtype AheadT m a = AheadT {getAheadT :: Stream m a}
623− deriving (MonadTrans, Foldable, Traversable)
622+ deriving (MonadTrans)
624
623
625-- | A serial IO stream of elements of type @a@ with concurrent lookahead. See
624-- | A serial IO stream of elements of type @a@ with concurrent lookahead. See
626-- 'AheadT' documentation for more details.
625-- 'AheadT' documentation for more details.
src/Streamly/Streams/Async.hs+2−3
@@ -1,6 +1,5 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE ConstraintKinds #-}
3−{-# LANGUAGE DeriveTraversable #-}
4{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving#-}
5{-# LANGUAGE GeneralizedNewtypeDeriving#-}
@@ -636,7 +635,7 @@ consMAsync m r = K.yieldM m `asyncS` r
636--
635--
637-- @since 0.1.0
636-- @since 0.1.0
638newtype AsyncT m a = AsyncT {getAsyncT :: Stream m a}
637newtype AsyncT m a = AsyncT {getAsyncT :: Stream m a}
639− deriving (MonadTrans, Foldable, Traversable)
638+ deriving (MonadTrans)
640
639
641-- | A demand driven left biased parallely composing IO stream of elements of
640-- | A demand driven left biased parallely composing IO stream of elements of
642-- type @a@. See 'AsyncT' documentation for more details.
641-- type @a@. See 'AsyncT' documentation for more details.
@@ -763,7 +762,7 @@ wAsync m1 m2 = fromStream $ Stream $ \st stp sng yld ->
763--
762--
764-- @since 0.2.0
763-- @since 0.2.0
765newtype WAsyncT m a = WAsyncT {getWAsyncT :: Stream m a}
764newtype WAsyncT m a = WAsyncT {getWAsyncT :: Stream m a}
766− deriving (MonadTrans, Foldable, Traversable)
765+ deriving (MonadTrans)
767
766
768-- | A round robin parallely composing IO stream of elements of type @a@.
767-- | A round robin parallely composing IO stream of elements of type @a@.
769-- See 'WAsyncT' documentation for more details.
768-- See 'WAsyncT' documentation for more details.
src/Streamly/Streams/Instances.hs+19
@@ -101,3 +101,22 @@ instance NFData a => NFData (STREAM Identity a) where { rnf = rnf1 }; \
101instance NFData1 (STREAM Identity) where { \
101instance NFData1 (STREAM Identity) where { \
102 {-# INLINE liftRnf #-}; \
102 {-# INLINE liftRnf #-}; \
103 liftRnf r = runIdentity . P.foldl' (\_ x -> r x) () }
103 liftRnf r = runIdentity . P.foldl' (\_ x -> r x) () }
104+
105+-------------------------------------------------------------------------------
106+-- Foldable
107+-------------------------------------------------------------------------------
108+
109+#define FOLDABLE_INSTANCE(STREAM) \
110+instance (Foldable m, Monad m) => Foldable (STREAM m) where { \
111+ {-# INLINE foldMap #-}; \
112+ foldMap f = fold . P.foldr mappend mempty . fmap f }
113+
114+-------------------------------------------------------------------------------
115+-- Traversable
116+-------------------------------------------------------------------------------
117+
118+#define TRAVERSABLE_INSTANCE(STREAM) \
119+instance Traversable (STREAM Identity) where { \
120+ {-# INLINE traverse #-}; \
121+ traverse f s = runIdentity $ P.foldr consA (pure mempty) s \
122+ where { consA x ys = liftA2 (K.cons) (f x) ys }}
src/Streamly/Streams/Parallel.hs+1−2
@@ -1,6 +1,5 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE ConstraintKinds #-}
3−{-# LANGUAGE DeriveTraversable #-}
4{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving#-}
5{-# LANGUAGE GeneralizedNewtypeDeriving#-}
@@ -326,7 +325,7 @@ x |&. f = f |$. x
326--
325--
327-- @since 0.1.0
326-- @since 0.1.0
328newtype ParallelT m a = ParallelT {getParallelT :: Stream m a}
327newtype ParallelT m a = ParallelT {getParallelT :: Stream m a}
329− deriving (MonadTrans, Foldable, Traversable)
328+ deriving (MonadTrans)
330
329
331-- | A parallely composing IO stream of elements of type @a@.
330-- | A parallely composing IO stream of elements of type @a@.
332-- See 'ParallelT' documentation for more details.
331-- See 'ParallelT' documentation for more details.
src/Streamly/Streams/Prelude.hs+16−3
@@ -27,6 +27,8 @@ module Streamly.Streams.Prelude
27 , toList
27 , toList
28
28
29 -- * Fold operations
29 -- * Fold operations
30+ , foldrM
31+ , foldr
30 , foldl'
32 , foldl'
31
33
32 -- * Zip style operations
34 -- * Zip style operations
@@ -40,6 +42,9 @@ module Streamly.Streams.Prelude
40 )
42 )
41where
43where
42
44
45+import Prelude hiding (foldr)
46+import qualified Prelude
47+
43#ifdef USE_STREAMK_ONLY
48#ifdef USE_STREAMK_ONLY
44import qualified Streamly.Streams.StreamK as S
49import qualified Streamly.Streams.StreamK as S
45#else
50#else
@@ -89,6 +94,14 @@ toList m = S.toList $ toStreamS m
89-- Folds
94-- Folds
90------------------------------------------------------------------------------
95------------------------------------------------------------------------------
91
96
97+{-# INLINE foldrM #-}
98+foldrM :: (Monad m, IsStream t) => (a -> b -> m b) -> b -> t m a -> m b
99+foldrM step acc m = S.foldrM step acc $ toStreamS m
100+
101+{-# INLINE foldr #-}
102+foldr :: (Monad m, IsStream t) => (a -> b -> b) -> b -> t m a -> m b
103+foldr f = foldrM (\a b -> return (f a b))
104+
92-- | Strict left associative fold.
105-- | Strict left associative fold.
93--
106--
94-- @since 0.2.0
107-- @since 0.2.0
@@ -129,7 +142,7 @@ cmpBy f m1 m2 = D.cmpBy f (D.toStreamD m1) (D.toStreamD m2)
129{-# INLINABLE foldWith #-}
142{-# INLINABLE foldWith #-}
130foldWith :: (IsStream t, Foldable f)
143foldWith :: (IsStream t, Foldable f)
131 => (t m a -> t m a -> t m a) -> f (t m a) -> t m a
144 => (t m a -> t m a -> t m a) -> f (t m a) -> t m a
132−foldWith f = foldr f K.nil
145+foldWith f = Prelude.foldr f K.nil
133
146
134-- | A variant of 'foldMap' that allows you to map a monadic streaming action
147-- | A variant of 'foldMap' that allows you to map a monadic streaming action
135-- on a 'Foldable' container and then fold it using the specified stream sum
148-- on a 'Foldable' container and then fold it using the specified stream sum
@@ -141,7 +154,7 @@ foldWith f = foldr f K.nil
141{-# INLINABLE foldMapWith #-}
154{-# INLINABLE foldMapWith #-}
142foldMapWith :: (IsStream t, Foldable f)
155foldMapWith :: (IsStream t, Foldable f)
143 => (t m b -> t m b -> t m b) -> (a -> t m b) -> f a -> t m b
156 => (t m b -> t m b -> t m b) -> (a -> t m b) -> f a -> t m b
144−foldMapWith f g = foldr (f . g) K.nil
157+foldMapWith f g = Prelude.foldr (f . g) K.nil
145
158
146-- | Like 'foldMapWith' but with the last two arguments reversed i.e. the
159-- | Like 'foldMapWith' but with the last two arguments reversed i.e. the
147-- monadic streaming function is the last argument.
160-- monadic streaming function is the last argument.
@@ -150,4 +163,4 @@ foldMapWith f g = foldr (f . g) K.nil
150{-# INLINABLE forEachWith #-}
163{-# INLINABLE forEachWith #-}
151forEachWith :: (IsStream t, Foldable f)
164forEachWith :: (IsStream t, Foldable f)
152 => (t m b -> t m b -> t m b) -> f a -> (a -> t m b) -> t m b
165 => (t m b -> t m b -> t m b) -> f a -> (a -> t m b) -> t m b
153−forEachWith f xs g = foldr (f . g) K.nil xs
166+forEachWith f xs g = Prelude.foldr (f . g) K.nil xs
src/Streamly/Streams/Serial.hs+11−4
@@ -1,6 +1,5 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE ConstraintKinds #-}
3−{-# LANGUAGE DeriveTraversable #-}
4{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving#-}
5{-# LANGUAGE GeneralizedNewtypeDeriving#-}
@@ -43,6 +42,7 @@ module Streamly.Streams.Serial
43 )
42 )
44where
43where
45
44
45+import Control.Applicative (liftA2)
46import Control.DeepSeq (NFData(..), NFData1(..), rnf1)
46import Control.DeepSeq (NFData(..), NFData1(..), rnf1)
47import Control.Monad (ap)
47import Control.Monad (ap)
48import Control.Monad.Base (MonadBase(..), liftBaseDefault)
48import Control.Monad.Base (MonadBase(..), liftBaseDefault)
@@ -52,7 +52,8 @@ import Control.Monad.IO.Class (MonadIO(..))
52import Control.Monad.Reader.Class (MonadReader(..))
52import Control.Monad.Reader.Class (MonadReader(..))
53import Control.Monad.State.Class (MonadState(..))
53import Control.Monad.State.Class (MonadState(..))
54import Control.Monad.Trans.Class (MonadTrans(lift))
54import Control.Monad.Trans.Class (MonadTrans(lift))
55−import Data.Functor.Identity (Identity, runIdentity)
55+import Data.Functor.Identity (Identity(..), runIdentity)
56+import Data.Foldable (fold)
56import Data.Semigroup (Semigroup(..))
57import Data.Semigroup (Semigroup(..))
57import GHC.Exts (IsList(..), IsString(..))
58import GHC.Exts (IsList(..), IsString(..))
58import Text.Read (Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec,
59import Text.Read (Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec,
@@ -129,7 +130,7 @@ import qualified Streamly.Streams.StreamD as D
129--
130--
130-- @since 0.2.0
131-- @since 0.2.0
131newtype SerialT m a = SerialT {getSerialT :: Stream m a}
132newtype SerialT m a = SerialT {getSerialT :: Stream m a}
132− deriving (Semigroup, Monoid, MonadTrans, Foldable, Traversable)
133+ deriving (Semigroup, Monoid, MonadTrans)
133
134
134-- | A serial IO stream of elements of type @a@. See 'SerialT' documentation
135-- | A serial IO stream of elements of type @a@. See 'SerialT' documentation
135-- for more details.
136-- for more details.
@@ -249,7 +250,7 @@ MONAD_COMMON_INSTANCES(SerialT,)
249--
250--
250-- @since 0.2.0
251-- @since 0.2.0
251newtype WSerialT m a = WSerialT {getWSerialT :: Stream m a}
252newtype WSerialT m a = WSerialT {getWSerialT :: Stream m a}
252− deriving (MonadTrans, Foldable, Traversable)
253+ deriving (MonadTrans)
253
254
254-- | An interleaving serial IO stream of elements of type @a@. See 'WSerialT'
255-- | An interleaving serial IO stream of elements of type @a@. See 'WSerialT'
255-- documentation for more details.
256-- documentation for more details.
@@ -353,3 +354,9 @@ MONAD_COMMON_INSTANCES(WSerialT,)
353
354
354LIST_INSTANCES(SerialT)
355LIST_INSTANCES(SerialT)
355LIST_INSTANCES(WSerialT)
356LIST_INSTANCES(WSerialT)
357+
358+FOLDABLE_INSTANCE(SerialT)
359+FOLDABLE_INSTANCE(WSerialT)
360+
361+TRAVERSABLE_INSTANCE(SerialT)
362+TRAVERSABLE_INSTANCE(WSerialT)
src/Streamly/Streams/StreamD.hs−15
@@ -134,7 +134,6 @@ import Prelude
134
134
135import Streamly.SVar (MonadAsync, State(..), defState, rstState)
135import Streamly.SVar (MonadAsync, State(..), defState, rstState)
136
136
137−import qualified Data.Foldable as F
138import qualified Streamly.Streams.StreamK as K
137import qualified Streamly.Streams.StreamK as K
139
138
140------------------------------------------------------------------------------
139------------------------------------------------------------------------------
@@ -157,20 +156,6 @@ instance Functor (Step s) where
157-- current state, and the current state.
156-- current state, and the current state.
158data Stream m a = forall s. Stream (State K.Stream m a -> s -> m (Step s a)) s
157data Stream m a = forall s. Stream (State K.Stream m a -> s -> m (Step s a)) s
159
158
160−instance (Foldable m, Monad m) => Foldable (Stream m) where
161− {-# INLINE foldMap #-}
162− foldMap f = F.fold . toFoldable . map f
163− where
164− toFoldable :: (Monad m, Monoid a) => Stream m a -> m a
165− toFoldable = foldr mappend mempty
166−
167−instance (Traversable m, Monad m) => Traversable (Stream m) where
168− {-# INLINE traverse #-}
169− traverse f = sequenceA . fmap f
170−
171− {-# INLINE sequenceA #-}
172− sequenceA = traverse id
173−
174------------------------------------------------------------------------------
159------------------------------------------------------------------------------
175-- Construction
160-- Construction
176------------------------------------------------------------------------------
161------------------------------------------------------------------------------
src/Streamly/Streams/StreamK.hs−15
@@ -153,7 +153,6 @@ import Prelude
153 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
153 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
154 maximum, elem, notElem, null, head, tail, init, zipWith, lookup,
154 maximum, elem, notElem, null, head, tail, init, zipWith, lookup,
155 foldr1)
155 foldr1)
156−import qualified Data.Foldable as F
157import qualified Prelude
156import qualified Prelude
158
157
159import Streamly.SVar
158import Streamly.SVar
@@ -189,20 +188,6 @@ newtype Stream m a =
189 -> m r
188 -> m r
190 }
189 }
191
190
192−instance (Foldable m, Monad m) => Foldable (Stream m) where
193− {-# INLINE foldMap #-}
194− foldMap f = F.fold . toFoldable . map f
195− where
196− toFoldable :: (Monad m, Monoid a) => Stream m a -> m a
197− toFoldable = foldr mappend mempty
198−
199−instance (Traversable m, Monad m) => Traversable (Stream m) where
200− {-# INLINE traverse #-}
201− traverse f = sequenceA . fmap f
202−
203− {-# INLINE sequenceA #-}
204− sequenceA = traverse id
205−
206-- XXX make this the default "unStream"
191-- XXX make this the default "unStream"
207-- | unwraps the Stream type producing the stream function that can be run with
192-- | unwraps the Stream type producing the stream function that can be run with
208-- continuations.
193-- continuations.
src/Streamly/Streams/Zip.hs+7−3
@@ -1,6 +1,5 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE ConstraintKinds #-}
3−{-# LANGUAGE DeriveTraversable #-}
4{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving#-}
5{-# LANGUAGE GeneralizedNewtypeDeriving#-}
@@ -39,8 +38,10 @@ module Streamly.Streams.Zip
39 )
38 )
40where
39where
41
40
41+import Control.Applicative (liftA2)
42import Control.DeepSeq (NFData(..), NFData1(..), rnf1)
42import Control.DeepSeq (NFData(..), NFData1(..), rnf1)
43import Data.Functor.Identity (Identity, runIdentity)
43import Data.Functor.Identity (Identity, runIdentity)
44+import Data.Foldable (fold)
44import Data.Semigroup (Semigroup(..))
45import Data.Semigroup (Semigroup(..))
45import GHC.Exts (IsList(..), IsString(..))
46import GHC.Exts (IsList(..), IsString(..))
46import Text.Read (Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec,
47import Text.Read (Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec,
@@ -80,7 +81,7 @@ import qualified Streamly.Streams.StreamK as K
80--
81--
81-- @since 0.2.0
82-- @since 0.2.0
82newtype ZipSerialM m a = ZipSerialM {getZipSerialM :: Stream m a}
83newtype ZipSerialM m a = ZipSerialM {getZipSerialM :: Stream m a}
83− deriving (Semigroup, Monoid, Foldable, Traversable)
84+ deriving (Semigroup, Monoid)
84
85
85-- |
86-- |
86-- @since 0.1.0
87-- @since 0.1.0
@@ -128,6 +129,9 @@ instance Monad m => Applicative (ZipSerialM m) where
128 pure = ZipSerialM . K.repeat
129 pure = ZipSerialM . K.repeat
129 m1 <*> m2 = fromStream $ K.zipWith id (toStream m1) (toStream m2)
130 m1 <*> m2 = fromStream $ K.zipWith id (toStream m1) (toStream m2)
130
131
132+FOLDABLE_INSTANCE(ZipSerialM)
133+TRAVERSABLE_INSTANCE(ZipSerialM)
134+
131------------------------------------------------------------------------------
135------------------------------------------------------------------------------
132-- Parallel Zipping
136-- Parallel Zipping
133------------------------------------------------------------------------------
137------------------------------------------------------------------------------
@@ -176,7 +180,7 @@ zipAsyncWithM f m1 m2 = fromStream $ Stream $ \st stp sng yld -> do
176--
180--
177-- @since 0.2.0
181-- @since 0.2.0
178newtype ZipAsyncM m a = ZipAsyncM {getZipAsyncM :: Stream m a}
182newtype ZipAsyncM m a = ZipAsyncM {getZipAsyncM :: Stream m a}
179− deriving (Semigroup, Monoid, Foldable, Traversable)
183+ deriving (Semigroup, Monoid)
180
184
181-- | An IO stream whose applicative instance zips streams wAsyncly.
185-- | An IO stream whose applicative instance zips streams wAsyncly.
182--
186--
test/PureStreams.hs+17−1
@@ -59,9 +59,13 @@ main = hspec $ do
59 [(x,y) | x <- [1..2], y <- [1..2]] `shouldBe`
59 [(x,y) | x <- [1..2], y <- [1..2]] `shouldBe`
60 ([(1,1), (1,2), (2,1), (2,2)] :: SerialT Identity (Int, Int))
60 ([(1,1), (1,2), (2,1), (2,2)] :: SerialT Identity (Int, Int))
61
61
62− it "Foldable (sum)" $ sum (S.fromList [1..3] :: SerialT Identity Int)
62+ it "Foldable (sum)" $ sum ([1..3] :: SerialT Identity Int)
63 `shouldBe` 6
63 `shouldBe` 6
64
64
65+ it "Traversable (mapM)" $
66+ mapM return ([1..10] :: SerialT Identity Int)
67+ `shouldReturn` [1..10]
68+
65 describe "OverloadedStrings for 'SerialT Identity' type" $ do
69 describe "OverloadedStrings for 'SerialT Identity' type" $ do
66 it "overloaded strings" $ do
70 it "overloaded strings" $ do
67 ("hello" :: SerialT Identity Char) `shouldBe` S.fromList "hello"
71 ("hello" :: SerialT Identity Char) `shouldBe` S.fromList "hello"
@@ -131,12 +135,20 @@ main = hspec $ do
131
135
132 it "Foldable (sum)" $ sum ([1..3] :: List Int) `shouldBe` 6
136 it "Foldable (sum)" $ sum ([1..3] :: List Int) `shouldBe` 6
133
137
138+ it "Traversable (mapM)" $
139+ mapM return ([1..10] :: List Int)
140+ `shouldReturn` [1..10]
141+
134 describe "OverloadedStrings for List type" $ do
142 describe "OverloadedStrings for List type" $ do
135 it "overloaded strings" $ do
143 it "overloaded strings" $ do
136 ("hello" :: List Char) `shouldBe` GHC.fromList "hello"
144 ("hello" :: List Char) `shouldBe` GHC.fromList "hello"
137
145
138 it "pattern matches" $ do
146 it "pattern matches" $ do
147+#if __GLASGOW_HASKELL__ >= 802
139 case "" of
148 case "" of
149+#else
150+ case "" :: List Char of
151+#endif
140 Nil -> return ()
152 Nil -> return ()
141 _ -> expectationFailure "not reached"
153 _ -> expectationFailure "not reached"
142
154
@@ -201,6 +213,10 @@ main = hspec $ do
201
213
202 it "Foldable (sum)" $ sum ([1..3] :: ZipList Int) `shouldBe` 6
214 it "Foldable (sum)" $ sum ([1..3] :: ZipList Int) `shouldBe` 6
203
215
216+ it "Traversable (mapM)" $
217+ mapM return ([1..10] :: ZipList Int)
218+ `shouldReturn` [1..10]
219+
204 it "Applicative Zip" $ do
220 it "Applicative Zip" $ do
205 (,) <$> "abc" <*> [1..3] `shouldBe`
221 (,) <$> "abc" <*> [1..3] `shouldBe`
206 ([('a',1),('b',2),('c',3)] :: ZipList (Char, Int))
222 ([('a',1),('b',2),('c',3)] :: ZipList (Char, Int))