on master help sign in
Move examples from Streamly module to examples dir
c5f97f0Harendra Kumar
.travis.yml+1−1
@@ -121,7 +121,7 @@ matrix:
121
121
122 # Note COVERALLS (hpc-coveralls) works only with cabal build.
122 # Note COVERALLS (hpc-coveralls) works only with cabal build.
123 # For this to succeed you have to add your project to coveralls.io first
123 # For this to succeed you have to add your project to coveralls.io first
124− - env: BUILD=cabal CABALVER=2.0 GHCVER=8.2.2 COVERALLS_OPTIONS="--coverage-mode=StrictlyFullLines --exclude-dir=test test properties"
124+ - env: BUILD=cabal CABALVER=2.0 GHCVER=8.2.2 COVERALLS_OPTIONS="--coverage-mode=StrictlyFullLines --exclude-dir=test test properties loops nested-loops parallel-loops"
125 addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2], sources: [hvr-ghc]}}
125 addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2], sources: [hvr-ghc]}}
126
126
127 # --------------------------------------------------------------------------
127 # --------------------------------------------------------------------------
examples/AcidRain.hs+2−4
@@ -3,8 +3,6 @@
3-- This example is adapted from Gabriel Gonzalez's pipes-concurrency package.
3-- This example is adapted from Gabriel Gonzalez's pipes-concurrency package.
4-- https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html
4-- https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html
5
5
6−module Streamly.Examples.AcidRainGame where
7−
8import Streamly
6import Streamly
9import Control.Concurrent (threadDelay)
7import Control.Concurrent (threadDelay)
10import Control.Monad (when)
8import Control.Monad (when)
@@ -38,8 +36,8 @@ game = do
38 when (h <= 0) $ fail "You die!"
36 when (h <= 0) $ fail "You die!"
39 liftIO $ putStrLn $ "Health = " ++ show h
37 liftIO $ putStrLn $ "Health = " ++ show h
40
38
41−acidRainGame :: IO ()
39+main :: IO ()
42−acidRainGame = do
40+main = do
43 putStrLn "Your health is deteriorating due to acid rain,\
41 putStrLn "Your health is deteriorating due to acid rain,\
44 \ type \"potion\" or \"quit\""
42 \ type \"potion\" or \"quit\""
45 _ <- runStateT (runStream game) 60
43 _ <- runStateT (runStream game) 60
examples/CirclingSquare.hs+5−6
@@ -1,11 +1,10 @@
1-- Adapted from the Yampa package.
1-- Adapted from the Yampa package.
2−-- Displays a square moving in a circle. To move the position drag the mouse.
2+-- Displays a square moving in a circle. To move the position drag it with the
3+-- mouse.
3--
4--
4-- Requires the SDL package, assuming streamly has already been built, you can
5-- Requires the SDL package, assuming streamly has already been built, you can
5-- compile it like this:
6-- compile it like this:
6−-- stack ghc --package SDL circle-mouse.hs
7+-- stack ghc --package SDL CirclingSquare.hs
7−
8−module Streamly.Examples.CirclingSquare where
9
8
10import Data.IORef
9import Data.IORef
11import Graphics.UI.SDL as SDL
10import Graphics.UI.SDL as SDL
@@ -84,8 +83,8 @@ updateDisplay cref = withClock clock refreshRate displaySquare
84 let t = (fromIntegral time) * speed / 1000000
83 let t = (fromIntegral time) * speed / 1000000
85 in display (x + cos t * radius, y + sin t * radius)
84 in display (x + cos t * radius, y + sin t * radius)
86
85
87−circlingSquare :: IO ()
86+main :: IO ()
88−circlingSquare = do
87+main = do
89 sdlInit
88 sdlInit
90 cref <- newIORef (0,0)
89 cref <- newIORef (0,0)
91 runStream $ once (updateController cref)
90 runStream $ once (updateController cref)
examples/ListDir.hs+5−5
@@ -1,15 +1,15 @@
1−module Streamly.Examples.ListDirRecursive where
2−
3import Path.IO (listDir, getCurrentDir)
1import Path.IO (listDir, getCurrentDir)
4import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
2import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
5import Streamly (runStream, coparallely)
3import Streamly (runStream, coparallely)
6import Streamly.Prelude (once)
4import Streamly.Prelude (once)
7
5
6+-- | List the current directory recursively using concurrent processing
7+--
8−-- | This example demonstrates that there is little difference between regular
8+-- This example demonstrates that there is little difference between regular
9-- IO code and concurrent streamly code. You can just remove
9-- IO code and concurrent streamly code. You can just remove
10-- 'runStream . coparallely' and this becomes your regular IO code.
10-- 'runStream . coparallely' and this becomes your regular IO code.
11−listDirRecursive :: IO ()
11+main :: IO ()
12−listDirRecursive = do
12+main = do
13 hSetBuffering stdout LineBuffering
13 hSetBuffering stdout LineBuffering
14 runStream . coparallely $ getCurrentDir >>= readdir
14 runStream . coparallely $ getCurrentDir >>= readdir
15 where readdir d = do
15 where readdir d = do
examples/MergeSort.hs+2−4
@@ -1,7 +1,5 @@
1{-# LANGUAGE FlexibleContexts #-}
1{-# LANGUAGE FlexibleContexts #-}
2
2
3−module Streamly.Examples.MergeSortedStreams where
4−
5import Data.Word
3import Data.Word
6import System.Random (getStdGen, randoms)
4import System.Random (getStdGen, randoms)
7import Data.List (sort)
5import Data.List (sort)
@@ -36,7 +34,7 @@ merge a b = do
36 then (return y) <> merge (return x <> ma) mb
34 then (return y) <> merge (return x <> ma) mb
37 else (return x) <> merge ma (return y <> mb)
35 else (return x) <> merge ma (return y <> mb)
38
36
39−mergeSortedStreams :: IO ()
37+main :: IO ()
40−mergeSortedStreams = do
38+main = do
41 xs <- A.toList $ mergeAsync getSorted getSorted
39 xs <- A.toList $ mergeAsync getSorted getSorted
42 putStrLn $ show $ length xs
40 putStrLn $ show $ length xs
examples/README.md+38−2
@@ -1,8 +1,44 @@
1−For better examples see the Streamly.Examples module.
1+# Running The Examples
2
2
3+## Running directly using stack
3You can run these examples using `stack` like this:
4You can run these examples using `stack` like this:
4
5
5```
6```
6$ stack build
7$ stack build
7−$ stack loop.hs
8+$ stack AcidRain.hs
9+```
10+
11+Note: This method may not work for `CirclingSquare.hs` SDL animation example.
12+
13+## Build and run
14+
15+Build the library with the `examples` flag on e.g.
16+
17+```
18+stack build --flag streamly:examples
19+cabal new-build --flags examples
20+```
21+
22+Then run the executables, for example:
23+
24+```
25+stack exec AcidRain
26+```
27+
28+The executable name are the same as the filenames.
29+
30+## Running the SDL animation example
31+
32+To include the SDL examples as well build with `examples-sdl` flag:
33+
34+```
35+stack build --flag streamly:examples-sdl
36+cabal new-build --flags examples-sdl
37+```
38+
39+Make sure that you have the SDL OS package installed on your system and the
40+headers are visible to Haskell build tool.
41+
42+```
43+stack exec CirclingSquare
8```
44```
examples/SearchQuery.hs+8−6
@@ -1,13 +1,15 @@
1−module Streamly.Examples.SearchEngineQuery where
2−
3import Streamly
1import Streamly
4import Streamly.Prelude (once)
2import Streamly.Prelude (once)
5import Network.HTTP.Simple
3import Network.HTTP.Simple
6
4
7−-- Runs three search engine queries in parallel.
5+-- | Runs three search engine queries in parallel and prints the search engine
8−searchEngineQuery :: IO ()
6+-- names in the fastest first order.
9−searchEngineQuery = do
7+--
8+-- Does it twice using two different ways.
9+--
10+main :: IO ()
11+main = do
10− putStrLn "Using parallel alternative"
12+ putStrLn "Using parallel semigroup composition"
11 runStream . parallely $ google <> bing <> duckduckgo
13 runStream . parallely $ google <> bing <> duckduckgo
12
14
13 putStrLn "\nUsing parallel applicative zip"
15 putStrLn "\nUsing parallel applicative zip"
streamly.cabal+81−40
@@ -35,6 +35,7 @@ cabal-version: >= 1.10
35extra-source-files:
35extra-source-files:
36 Changelog.md
36 Changelog.md
37 README.md
37 README.md
38+ bench.sh
38 charts/comparative/AllOperationsataGlance.svg
39 charts/comparative/AllOperationsataGlance.svg
39 charts/comparative/ComposingPipelineStages.svg
40 charts/comparative/ComposingPipelineStages.svg
40 stack-7.10.yaml
41 stack-7.10.yaml
@@ -59,6 +60,10 @@ flag examples-sdl
59 manual: True
60 manual: True
60 default: False
61 default: False
61
62
63+-------------------------------------------------------------------------------
64+-- Library
65+-------------------------------------------------------------------------------
66+
62library
67library
63 hs-source-dirs: src
68 hs-source-dirs: src
64 other-modules: Streamly.Core
69 other-modules: Streamly.Core
@@ -69,16 +74,6 @@ library
69 , Streamly.Tutorial
74 , Streamly.Tutorial
70 , Streamly
75 , Streamly
71
76
72− if flag(examples) || flag(examples-sdl)
73− exposed-modules: Streamly.Examples
74− , Streamly.Examples.SearchEngineQuery
75− , Streamly.Examples.ListDirRecursive
76− , Streamly.Examples.MergeSortedStreams
77− , Streamly.Examples.AcidRainGame
78−
79− if flag(examples-sdl)
80− exposed-modules: Streamly.Examples.CirclingSquare
81−
82 default-language: Haskell2010
77 default-language: Haskell2010
83 ghc-options: -Wall
78 ghc-options: -Wall
84
79
@@ -95,8 +90,6 @@ library
95 -Wredundant-constraints
90 -Wredundant-constraints
96 -Wnoncanonical-monad-instances
91 -Wnoncanonical-monad-instances
97 -Wnoncanonical-monadfail-instances
92 -Wnoncanonical-monadfail-instances
98− if flag(examples-sdl)
99− cpp-options: -DEXAMPLES_SDL
100
93
101 build-depends: base >= 4.8 && < 5
94 build-depends: base >= 4.8 && < 5
102 , atomic-primops >= 0.8 && < 0.9
95 , atomic-primops >= 0.8 && < 0.9
@@ -114,15 +107,9 @@ library
114 build-depends:
107 build-depends:
115 semigroups >= 0.18 && < 0.19
108 semigroups >= 0.18 && < 0.19
116
109
117− if flag(examples) || flag(examples-sdl)
110+-------------------------------------------------------------------------------
118− build-Depends:
111+-- Test suites
119− http-conduit >= 2.2.2 && < 2.4
112+-------------------------------------------------------------------------------
120− , path-io >= 0.1.0 && < 1.4
121− , random >= 1.0.0 && < 1.2
122−
123− if flag(examples-sdl)
124− build-Depends:
125− SDL >= 0.6.5 && < 0.7
126
113
127test-suite test
114test-suite test
128 type: exitcode-stdio-1.0
115 type: exitcode-stdio-1.0
@@ -175,6 +162,39 @@ test-suite properties
175 , hspec >= 2.0 && < 3
162 , hspec >= 2.0 && < 3
176 default-language: Haskell2010
163 default-language: Haskell2010
177
164
165+test-suite loops
166+ type: exitcode-stdio-1.0
167+ default-language: Haskell2010
168+ main-is: loops.hs
169+ hs-source-dirs: test
170+ build-Depends:
171+ streamly
172+ , base >= 4.8 && < 5
173+
174+test-suite nested-loops
175+ type: exitcode-stdio-1.0
176+ default-language: Haskell2010
177+ main-is: nested-loops.hs
178+ hs-source-dirs: test
179+ build-Depends:
180+ streamly
181+ , base >= 4.8 && < 5
182+ , random >= 1.0.0 && < 1.2
183+
184+test-suite parallel-loops
185+ type: exitcode-stdio-1.0
186+ default-language: Haskell2010
187+ main-is: parallel-loops.hs
188+ hs-source-dirs: test
189+ build-Depends:
190+ streamly
191+ , base >= 4.8 && < 5
192+ , random >= 1.0.0 && < 1.2
193+
194+-------------------------------------------------------------------------------
195+-- Benchmarks
196+-------------------------------------------------------------------------------
197+
178benchmark linear
198benchmark linear
179 type: exitcode-stdio-1.0
199 type: exitcode-stdio-1.0
180 hs-source-dirs: benchmark
200 hs-source-dirs: benchmark
@@ -229,10 +249,6 @@ benchmark nested
229 , random >= 1.0 && < 2.0
249 , random >= 1.0 && < 2.0
230 , gauge >= 0.2.1 && < 0.3
250 , gauge >= 0.2.1 && < 0.3
231
251
232−-------------------------------------------------------------------------------
233−-- Examples
234−-------------------------------------------------------------------------------
235−
236executable chart-linear
252executable chart-linear
237 default-language: Haskell2010
253 default-language: Haskell2010
238 hs-source-dirs: benchmark
254 hs-source-dirs: benchmark
@@ -259,37 +275,39 @@ executable chart-nested
259 else
275 else
260 buildable: False
276 buildable: False
261
277
278+-------------------------------------------------------------------------------
279+-- Examples
280+-------------------------------------------------------------------------------
281+
262−executable loops
282+executable SearchQuery
263 default-language: Haskell2010
283 default-language: Haskell2010
264− main-is: loops.hs
284+ main-is: SearchQuery.hs
265 hs-source-dirs: examples
285 hs-source-dirs: examples
266 if flag(examples) || flag(examples-sdl)
286 if flag(examples) || flag(examples-sdl)
267 buildable: True
287 buildable: True
268 build-Depends:
288 build-Depends:
269 streamly
289 streamly
270− , base >= 4.8 && < 5
290+ , base >= 4.8 && < 5
291+ , http-conduit >= 2.2.2 && < 2.4
271 else
292 else
272 buildable: False
293 buildable: False
273
294
274−executable nested-loops
295+executable ListDir
275 default-language: Haskell2010
296 default-language: Haskell2010
276− main-is: nested-loops.hs
297+ main-is: ListDir.hs
277 hs-source-dirs: examples
298 hs-source-dirs: examples
278 if flag(examples) || flag(examples-sdl)
299 if flag(examples) || flag(examples-sdl)
279 buildable: True
300 buildable: True
280 build-Depends:
301 build-Depends:
281 streamly
302 streamly
282− , base >= 4.8 && < 5
303+ , base >= 4.8 && < 5
283− , random >= 1.0.0 && < 1.2
304+ , path-io >= 0.1.0 && < 1.4
284− if impl(ghc < 8.0)
285− build-depends:
286− transformers >= 0.4 && < 0.6
287 else
305 else
288 buildable: False
306 buildable: False
289
307
290−executable parallel-loops
308+executable MergeSort
291 default-language: Haskell2010
309 default-language: Haskell2010
292− main-is: parallel-loops.hs
310+ main-is: MergeSort.hs
293 hs-source-dirs: examples
311 hs-source-dirs: examples
294 if flag(examples) || flag(examples-sdl)
312 if flag(examples) || flag(examples-sdl)
295 buildable: True
313 buildable: True
@@ -297,8 +315,31 @@ executable parallel-loops
297 streamly
315 streamly
298 , base >= 4.8 && < 5
316 , base >= 4.8 && < 5
299 , random >= 1.0.0 && < 1.2
317 , random >= 1.0.0 && < 1.2
300− if impl(ghc < 8.0)
318+ else
319+ buildable: False
320+
321+executable AcidRain
322+ default-language: Haskell2010
323+ main-is: AcidRain.hs
324+ hs-source-dirs: examples
325+ if flag(examples) || flag(examples-sdl)
326+ buildable: True
301− build-depends:
327+ build-Depends:
302− transformers >= 0.4 && < 0.6
328+ streamly
329+ , base >= 4.8 && < 5
330+ , mtl >= 2.2 && < 3
331+ else
332+ buildable: False
333+
334+executable CirclingSquare
335+ default-language: Haskell2010
336+ main-is: CirclingSquare.hs
337+ hs-source-dirs: examples
338+ if flag(examples-sdl)
339+ buildable: True
340+ build-Depends:
341+ streamly
342+ , base >= 4.8 && < 5
343+ , SDL >= 0.6.5 && < 0.7
303 else
344 else
304 buildable: False
345 buildable: False
test/loops.hs−14
@@ -41,10 +41,6 @@ main = do
41-- Serial (single-threaded) stream generator loops
41-- Serial (single-threaded) stream generator loops
42-------------------------------------------------------------------------------
42-------------------------------------------------------------------------------
43
43
44− -- In a <> composition the action on the left is executed and only after it
45− -- finished then the action on the right is executed. In other words the
46− -- actions are run serially.
47−
48 -- Generates a value and then loops. Can be used to generate an infinite
44 -- Generates a value and then loops. Can be used to generate an infinite
49 -- stream. Interleaves the generator and the consumer.
45 -- stream. Interleaves the generator and the consumer.
50 loopTail :: Int -> Stream Int
46 loopTail :: Int -> Stream Int
@@ -64,11 +60,6 @@ main = do
64-- Concurrent (multi-threaded) adaptive demand-based stream generator loops
60-- Concurrent (multi-threaded) adaptive demand-based stream generator loops
65-------------------------------------------------------------------------------
61-------------------------------------------------------------------------------
66
62
67− -- In a <| composition the action on the left is executed first. However,
68− -- if it is not fast enough to generate results at the consumer's speed
69− -- then the action on the right is also spawned concurrently. In other
70− -- words, both actions may run concurrently based on the need.
71−
72 loopTailA :: Int -> Stream Int
63 loopTailA :: Int -> Stream Int
73 loopTailA x = do
64 loopTailA x = do
74 once $ putStrLn "LoopTailA..."
65 once $ putStrLn "LoopTailA..."
@@ -82,8 +73,3 @@ main = do
82-------------------------------------------------------------------------------
73-------------------------------------------------------------------------------
83-- Parallel (fairly scheduled, multi-threaded) stream generator loops
74-- Parallel (fairly scheduled, multi-threaded) stream generator loops
84-------------------------------------------------------------------------------
75-------------------------------------------------------------------------------
85−
86− -- In a <|> composition both actions are run concurrently in a fair
87− -- manner, no one action is preferred over another. Both actions are
88− -- spawned right away in their own independent threads. In other words, the
89− -- actions will run concurrently.
test/nested-loops.hs+2
@@ -14,6 +14,8 @@ main = runStream $ do
14
14
15 where
15 where
16
16
17+ -- we can just use
18+ -- parallely $ mconcat $ replicate n $ once (...)
17 loop :: String -> Int -> StreamT IO String
19 loop :: String -> Int -> StreamT IO String
18 loop name n = do
20 loop name n = do
19 rnd <- once (randomIO :: IO Int)
21 rnd <- once (randomIO :: IO Int)
test/parallel-loops.hs+15−9
@@ -2,19 +2,25 @@ import Control.Concurrent (myThreadId, threadDelay)
2import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
2import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
3import System.Random (randomIO)
3import System.Random (randomIO)
4import Streamly
4import Streamly
5−import Streamly.Prelude (once)
5+import qualified Streamly.Prelude as S
6
6
7−main = runStream $ do
7+main = do
8− once $ hSetBuffering stdout LineBuffering
8+ hSetBuffering stdout LineBuffering
9+ runStream $ do
9− x <- loop "A" `parallel` loop "B"
10+ x <- S.take 10 $ loop "A" `parallel` loop "B"
10− once $ myThreadId >>= putStr . show
11+ S.once $ myThreadId >>= putStr . show
11− >> putStr " "
12+ >> putStr " got "
12− >> print x
13+ >> print x
13
14
14 where
15 where
15
16
17+ -- we can just use
18+ -- parallely $ cycle1 $ once (...)
16 loop :: String -> Stream (String, Int)
19 loop :: String -> Stream (String, Int)
17 loop name = do
20 loop name = do
18− once $ threadDelay 1000000
21+ S.once $ threadDelay 1000000
19− rnd <- once (randomIO :: IO Int)
22+ rnd <- S.once (randomIO :: IO Int)
23+ S.once $ myThreadId >>= putStr . show
24+ >> putStr " yielding "
25+ >> print rnd
20 return (name, rnd) `parallel` loop name
26 return (name, rnd) `parallel` loop name