on master help sign in
Fix the default stream type to SerialT
commit38d21d5193397df2737e9902c3810b53afbcaa17 authorHarendra Kumar <harendra.kumar@gmail.com> dateTue 17 Apr 2018, 21:56 (9 years ago) parent7a4b3fc
6 files changed+66−61
Changelog.md+8 src/Streamly/Examples/SearchEngineQuery.hs+1−1 src/Streamly/Prelude.hs+1−1 src/Streamly/Streams.hs+20−20 test/Main.hs+16−16 test/Prop.hs+20−23
Changelog.md+8
@@ -16,6 +16,14 @@
1616 different behavior for each type. See the documentation for more details. To
1717 adapt to this change replace any usage of `<|>` with `parallel` and
1818 `empty` with `nil`.
19+* Streams now default to the `SerialT` type unless explicitly specified using a
20+ type combinator. This also means that you do not have to explicitly specify a
21+ stream type now, the default will be used. This changes reduces puzzling type
22+ errors for beginners. It includes the following two changes:
23+ * Change the type of all stream elimination functions to `SerialT`. This
24+ makes sure that the stream type is always fixed at all exits.
25+ * Change the type combinators to only fix the argument stream type and
26+ the resulting stream type remains polymorphic.
1927* Change the type of `foldrM` to make it consistent with `foldrM` in base.
2028
2129### Deprecations
src/Streamly/Examples/SearchEngineQuery.hs+1−1
@@ -15,7 +15,7 @@ searchEngineQuery = do
1515 where
1616 get :: IsStream t => String -> t IO ()
1717 google, bing, duckduckgo :: IsStream t => t IO ()
18− get s = adapt . serially $ liftIO (httpNoBody (parseRequest_ s) >> putStrLn (show s))
18+ get s = serially $ liftIO (httpNoBody (parseRequest_ s) >> putStrLn (show s))
1919 google = get "https://www.google.com/search?q=haskell"
2020 bing = get "https://www.bing.com/search?q=haskell"
2121 duckduckgo = get "https://www.duckduckgo.com/?q=haskell"
src/Streamly/Prelude.hs+1−1
@@ -313,7 +313,7 @@ toHandle h m = go (toStream m)
313313
314314-- | Convert a stream into a list in the underlying monad.
315315{-# INLINABLE toList #-}
316−toList :: (IsStream t, Monad m) => t m a -> m [a]
316+toList :: Monad m => SerialT m a -> m [a]
317317toList = foldrM (\a xs -> return (a : xs)) []
318318
319319-- | Take first 'n' elements from the stream and discard the rest.
src/Streamly/Streams.hs+20−20
@@ -220,7 +220,7 @@ streamFold sv step blank m =
220220 in (S.runStream (toStream m)) sv blank yield
221221
222222-- | Run a streaming composition, discard the results.
223−runStream :: (Monad m, IsStream t) => t m a -> m ()
223+runStream :: Monad m => SerialT m a -> m ()
224224runStream m = go (toStream m)
225225 where
226226 go m1 =
@@ -232,7 +232,7 @@ runStream m = go (toStream m)
232232-- | Same as 'runStream'
233233{-# Deprecated runStreaming "Please use runStream instead." #-}
234234runStreaming :: (Monad m, IsStream t) => t m a -> m ()
235−runStreaming = runStream
235+runStreaming = runStream . adapt
236236
237237-- | Write a stream to an 'SVar' in a non-blocking manner. The stream can then
238238-- be read back from the SVar using 'fromSVar'.
@@ -1071,33 +1071,33 @@ adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
10711071adapt = fromStream . toStream
10721072
10731073-- | Interpret an ambiguously typed stream as 'SerialT'.
1074−serially :: SerialT m a -> SerialT m a
1075−serially x = x
1074+serially :: IsStream t => SerialT m a -> t m a
1075+serially = adapt
10761076
10771077-- | Interpret an ambiguously typed stream as 'InterleavedT'.
1078−interleaving :: InterleavedT m a -> InterleavedT m a
1079−interleaving x = x
1078+interleaving :: IsStream t => InterleavedT m a -> t m a
1079+interleaving = adapt
10801080
10811081-- | Interpret an ambiguously typed stream as 'AParallelT'.
1082−aparallely :: AParallelT m a -> AParallelT m a
1083−aparallely x = x
1082+aparallely :: IsStream t => AParallelT m a -> t m a
1083+aparallely = adapt
10841084
10851085-- | Same as 'aparallely'.
10861086{-# DEPRECATED asyncly "Please use aparallely instead." #-}
1087−asyncly :: AParallelT m a -> AParallelT m a
1087+asyncly :: IsStream t => AParallelT m a -> t m a
10881088asyncly = aparallely
10891089
10901090-- | Interpret an ambiguously typed stream as 'ParallelT'.
1091−parallely :: ParallelT m a -> ParallelT m a
1092−parallely x = x
1091+parallely :: IsStream t => ParallelT m a -> t m a
1092+parallely = adapt
10931093
10941094-- | Interpret an ambiguously typed stream as 'ZipSerial'.
1095−zipping :: ZipSerial m a -> ZipSerial m a
1096−zipping x = x
1095+zipping :: IsStream t => ZipSerial m a -> t m a
1096+zipping = adapt
10971097
10981098-- | Interpret an ambiguously typed stream as 'ZipAsync'.
1099−zippingAsync :: ZipAsync m a -> ZipAsync m a
1100−zippingAsync x = x
1099+zippingAsync :: IsStream t => ZipAsync m a -> t m a
1100+zippingAsync = adapt
11011101
11021102-------------------------------------------------------------------------------
11031103-- Running Streams, convenience functions specialized to types
@@ -1114,11 +1114,11 @@ runStreamT = runSerialT
11141114
11151115-- | Same as @runStream . interleaving@.
11161116runInterleavedT :: Monad m => InterleavedT m a -> m ()
1117−runInterleavedT = runStream
1117+runInterleavedT = runStream . interleaving
11181118
11191119-- | Same as @runStream . aparallely@.
11201120runAParallelT :: Monad m => AParallelT m a -> m ()
1121−runAParallelT = runStream
1121+runAParallelT = runStream . aparallely
11221122
11231123-- | Same as @runAParallelT@.
11241124{-# Deprecated runAsyncT "Please use runAParallelT instead." #-}
@@ -1127,11 +1127,11 @@ runAsyncT = runAParallelT
11271127
11281128-- | Same as @runStream . parallely@.
11291129runParallelT :: Monad m => ParallelT m a -> m ()
1130−runParallelT = runStream
1130+runParallelT = runStream . parallely
11311131
11321132-- | Same as @runStream . zipping@.
11331133runZipSerial :: Monad m => ZipSerial m a -> m ()
1134−runZipSerial = runStream
1134+runZipSerial = runStream . zipping
11351135
11361136{-# Deprecated runZipStream "Please use runZipSerial instead." #-}
11371137-- | Same as ZipSerial.
@@ -1140,7 +1140,7 @@ runZipStream = runZipSerial
11401140
11411141-- | Same as @runStream . zippingAsync@.
11421142runZipAsync :: Monad m => ZipAsync m a -> m ()
1143−runZipAsync = runStream
1143+runZipAsync = runStream . zippingAsync
11441144
11451145------------------------------------------------------------------------------
11461146-- Fold Utilities
test/Main.hs+16−16
@@ -139,8 +139,8 @@ main = hspec $ do
139139
140140 describe "Nested parallel and serial compositions" $ do
141141 let t = timed
142− p = adapt . parallely
143− s = adapt . serially
142+ p = parallely
143+ s = serially
144144 {-
145145 -- This is not correct, the result can also be [4,4,8,0,8,0,2,2]
146146 -- because of parallelism of [8,0] and [8,0].
@@ -375,14 +375,14 @@ timed :: MonadIO (t IO) => Int -> t IO Int
375375timed x = liftIO (threadDelay (x * 100000)) >> return x
376376
377377interleaveCheck :: (IsStream t, Semigroup (t IO Int))
378− => (t IO Int -> t IO Int) -> Spec
378+ => (t IO Int -> SerialT IO Int) -> Spec
379379interleaveCheck t =
380380 it "Interleave four" $
381381 (A.toList . t) ((singleton 0 <> singleton 1) <> (singleton 100 <> singleton 101))
382382 `shouldReturn` ([0, 100, 1, 101])
383383
384−parallelCheck :: (IsStream t, Semigroup (t IO Int), MonadIO (t IO))
385− => (t IO Int -> t IO Int) -> Spec
384+parallelCheck :: (Semigroup (t IO Int), MonadIO (t IO))
385+ => (t IO Int -> SerialT IO Int) -> Spec
386386parallelCheck t = do
387387 it "Parallel ordering left associated" $
388388 (A.toList . t) (((event 4 <> event 3) <> event 2) <> event 1)
@@ -395,7 +395,7 @@ parallelCheck t = do
395395 where event n = (liftIO $ threadDelay (n * 100000)) >> (return n)
396396
397397compose :: (IsStream t, Semigroup (t IO Int))
398− => (t IO Int -> t IO Int) -> t IO Int -> ([Int] -> [Int]) -> Spec
398+ => (t IO Int -> SerialT IO Int) -> t IO Int -> ([Int] -> [Int]) -> Spec
399399compose t z srt = do
400400 -- XXX these should get covered by the property tests
401401 it "Compose mempty, mempty" $
@@ -434,13 +434,13 @@ composeAndComposeSimple
434434 , Semigroup (t2 IO Int)
435435#endif
436436 )
437− => (t1 IO Int -> t1 IO Int)
437+ => (t1 IO Int -> SerialT IO Int)
438438 -> (t2 IO Int -> t2 IO Int)
439439 -> [[Int]] -> Spec
440440composeAndComposeSimple t1 t2 answer = do
441441 let rfold = adapt . t2 . foldMapWith (<>) return
442442 it "Compose right associated outer expr, right folded inner" $
443− ((A.toList. t1) (rfold [1,2,3] <> (rfold [4,5,6] <> rfold [7,8,9])))
443+ ((A.toList . t1) (rfold [1,2,3] <> (rfold [4,5,6] <> rfold [7,8,9])))
444444 `shouldReturn` (answer !! 0)
445445
446446 it "Compose left associated outer expr, right folded inner" $
@@ -463,10 +463,10 @@ loops
463463 -> ([Int] -> [Int])
464464 -> Spec
465465loops t tsrt hsrt = do
466− it "Tail recursive loop" $ (A.toList (loopTail 0) >>= return . tsrt)
466+ it "Tail recursive loop" $ ((A.toList . adapt) (loopTail 0) >>= return . tsrt)
467467 `shouldReturn` [0..3]
468468
469− it "Head recursive loop" $ (A.toList (loopHead 0) >>= return . hsrt)
469+ it "Head recursive loop" $ ((A.toList . adapt) (loopHead 0) >>= return . hsrt)
470470 `shouldReturn` [0..3]
471471
472472 where
@@ -482,7 +482,7 @@ loops t tsrt hsrt = do
482482
483483bindAndComposeSimple
484484 :: ( IsStream t1, IsStream t2, Semigroup (t2 IO Int), Monad (t2 IO))
485− => (t1 IO Int -> t1 IO Int)
485+ => (t1 IO Int -> SerialT IO Int)
486486 -> (t2 IO Int -> t2 IO Int)
487487 -> Spec
488488bindAndComposeSimple t1 t2 = do
@@ -499,7 +499,7 @@ bindAndComposeSimple t1 t2 = do
499499bindAndComposeHierarchy
500500 :: ( IsStream t1, Monad (t1 IO)
501501 , IsStream t2, Monad (t2 IO))
502− => (t1 IO Int -> t1 IO Int)
502+ => (t1 IO Int -> SerialT IO Int)
503503 -> (t2 IO Int -> t2 IO Int)
504504 -> ([t2 IO Int] -> t2 IO Int)
505505 -> Spec
@@ -550,14 +550,14 @@ mixedOps = do
550550 x <- return 1
551551 y <- return 2
552552 z <- do
553− x1 <- adapt . parallely $ return 1 <> return 2
553+ x1 <- parallely $ return 1 <> return 2
554554 liftIO $ return ()
555555 liftIO $ putStr ""
556− y1 <- adapt . aparallely $ return 1 <> return 2
556+ y1 <- aparallely $ return 1 <> return 2
557557 z1 <- do
558558 x11 <- return 1 <> return 2
559− y11 <- adapt . aparallely $ return 1 <> return 2
560− z11 <- adapt . interleaving $ return 1 <> return 2
559+ y11 <- aparallely $ return 1 <> return 2
560+ z11 <- interleaving $ return 1 <> return 2
561561 liftIO $ return ()
562562 liftIO $ putStr ""
563563 return (x11 + y11 + z11)
test/Prop.hs+20−23
@@ -36,7 +36,7 @@ equals eq stream list = do
3636
3737constructWithReplicateM
3838 :: IsStream t
39− => (t IO Int -> t IO Int)
39+ => (t IO Int -> SerialT IO Int)
4040 -> Word8
4141 -> Property
4242constructWithReplicateM op len =
@@ -47,11 +47,10 @@ constructWithReplicateM op len =
4747 equals (==) stream list
4848
4949transformFromList
50− :: IsStream t
51− => ([Int] -> t IO Int)
50+ :: ([Int] -> t IO Int)
5251 -> ([Int] -> [Int] -> Bool)
5352 -> ([Int] -> [Int])
54− -> (t IO Int -> t IO Int)
53+ -> (t IO Int -> SerialT IO Int)
5554 -> [Int]
5655 -> Property
5756transformFromList constr eq listOp op a =
@@ -61,9 +60,8 @@ transformFromList constr eq listOp op a =
6160 equals eq stream list
6261
6362foldFromList
64− :: IsStream t
65− => ([Int] -> t IO Int)
66− -> (t IO Int -> t IO Int)
63+ :: ([Int] -> t IO Int)
64+ -> (t IO Int -> SerialT IO Int)
6765 -> ([Int] -> [Int] -> Bool)
6866 -> [Int]
6967 -> Property
@@ -96,10 +94,10 @@ elemOp constr op streamOp listOp (x, xs) =
9694 equals (==) stream list
9795
9896functorOps
99− :: (IsStream t, Functor (t IO))
97+ :: Functor (t IO)
10098 => ([Int] -> t IO Int)
10199 -> String
102− -> (t IO Int -> t IO Int)
100+ -> (t IO Int -> SerialT IO Int)
103101 -> ([Int] -> [Int] -> Bool)
104102 -> Spec
105103functorOps constr desc t eq = do
@@ -110,7 +108,7 @@ transformOps
110108 :: IsStream t
111109 => ([Int] -> t IO Int)
112110 -> String
113− -> (t IO Int -> t IO Int)
111+ -> (t IO Int -> SerialT IO Int)
114112 -> ([Int] -> [Int] -> Bool)
115113 -> Spec
116114transformOps constr desc t eq = do
@@ -181,10 +179,9 @@ eliminationOps constr desc t = do
181179-- head/tail/last may depend on the order in case of parallel streams
182180-- so we test these only for serial streams.
183181serialEliminationOps
184− :: IsStream t
185− => ([Int] -> t IO Int)
182+ :: ([Int] -> t IO Int)
186183 -> String
187− -> (t IO Int -> t IO Int)
184+ -> (t IO Int -> SerialT IO Int)
188185 -> Spec
189186serialEliminationOps constr desc t = do
190187 prop (desc ++ " head") $ eliminateOp constr (wrapMaybe head) $ A.head . t
@@ -214,7 +211,7 @@ semigroupOps
214211#endif
215212 , Monoid (t IO Int))
216213 => String
217− -> (t IO Int -> t IO Int)
214+ -> (t IO Int -> SerialT IO Int)
218215 -> ([Int] -> [Int] -> Bool)
219216 -> Spec
220217semigroupOps desc t eq = do
@@ -222,9 +219,9 @@ semigroupOps desc t eq = do
222219 prop (desc ++ " mappend") $ foldFromList (foldMapWith mappend singleton) t eq
223220
224221applicativeOps
225− :: (IsStream t, Applicative (t IO))
222+ :: Applicative (t IO)
226223 => ([Int] -> t IO Int)
227− -> (t IO (Int, Int) -> t IO (Int, Int))
224+ -> (t IO (Int, Int) -> SerialT IO (Int, Int))
228225 -> ([(Int, Int)] -> [(Int, Int)] -> Bool)
229226 -> ([Int], [Int])
230227 -> Property
@@ -236,7 +233,7 @@ applicativeOps constr t eq (a, b) = monadicIO $ do
236233zipApplicative
237234 :: (IsStream t, Applicative (t IO))
238235 => ([Int] -> t IO Int)
239− -> (t IO (Int, Int) -> t IO (Int, Int))
236+ -> (t IO (Int, Int) -> SerialT IO (Int, Int))
240237 -> ([(Int, Int)] -> [(Int, Int)] -> Bool)
241238 -> ([Int], [Int])
242239 -> Property
@@ -252,7 +249,7 @@ zipApplicative constr t eq (a, b) = monadicIO $ do
252249zipMonadic
253250 :: (IsStream t, Monad (t IO))
254251 => ([Int] -> t IO Int)
255− -> (t IO (Int, Int) -> t IO (Int, Int))
252+ -> (t IO (Int, Int) -> SerialT IO (Int, Int))
256253 -> ([(Int, Int)] -> [(Int, Int)] -> Bool)
257254 -> ([Int], [Int])
258255 -> Property
@@ -271,9 +268,9 @@ zipMonadic constr t eq (a, b) =
271268 equals eq stream2 list
272269
273270monadThen
274− :: (IsStream t, Monad (t IO))
271+ :: Monad (t IO)
275272 => ([Int] -> t IO Int)
276− -> (t IO Int -> t IO Int)
273+ -> (t IO Int -> SerialT IO Int)
277274 -> ([Int] -> [Int] -> Bool)
278275 -> ([Int], [Int])
279276 -> Property
@@ -283,9 +280,9 @@ monadThen constr t eq (a, b) = monadicIO $ do
283280 equals eq stream list
284281
285282monadBind
286− :: (IsStream t, Monad (t IO))
283+ :: Monad (t IO)
287284 => ([Int] -> t IO Int)
288− -> (t IO Int -> t IO Int)
285+ -> (t IO Int -> SerialT IO Int)
289286 -> ([Int] -> [Int] -> Bool)
290287 -> ([Int], [Int])
291288 -> Property
@@ -313,7 +310,7 @@ main = hspec $ do
313310 `shouldReturn` (take 100 $ iterate (+ 1) 0)
314311
315312 let folded :: IsStream t => [a] -> t IO a
316− folded = adapt . serially . (\xs ->
313+ folded = serially . (\xs ->
317314 case xs of
318315 [x] -> return x -- singleton stream case
319316 _ -> foldMapWith (<>) return xs