on master help sign in
Move examples from Streamly module to examples dir
commitc5f97f0e3b450fa7b6e873db36bfdfb91ac15fd1 authorHarendra Kumar <harendra.kumar@gmail.com> dateFri 4 May 2018, 01:27 (8 years ago) parentf3dbbde
11 files changed+159−91
.travis.yml+1−1 examples/AcidRain.hs+2−4 examples/CirclingSquare.hs+5−6 examples/ListDir.hs+5−5 examples/MergeSort.hs+2−4 examples/README.md+38−2 examples/SearchQuery.hs+8−6 streamly.cabal+81−40 test/loops.hs−14 test/nested-loops.hs+2 test/parallel-loops.hs+15−9
.travis.yml+1−1
@@ -121,7 +121,7 @@ matrix:
121121
122122 # Note COVERALLS (hpc-coveralls) works only with cabal build.
123123 # 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"
125125 addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2], sources: [hvr-ghc]}}
126126
127127 # --------------------------------------------------------------------------
examples/AcidRain.hs+2−4
@@ -3,8 +3,6 @@
33-- This example is adapted from Gabriel Gonzalez's pipes-concurrency package.
44-- https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html
55
6−module Streamly.Examples.AcidRainGame where
7−
86import Streamly
97import Control.Concurrent (threadDelay)
108import Control.Monad (when)
@@ -38,8 +36,8 @@ game = do
3836 when (h <= 0) $ fail "You die!"
3937 liftIO $ putStrLn $ "Health = " ++ show h
4038
41−acidRainGame :: IO ()
42−acidRainGame = do
39+main :: IO ()
40+main = do
4341 putStrLn "Your health is deteriorating due to acid rain,\
4442 \ type \"potion\" or \"quit\""
4543 _ <- runStateT (runStream game) 60
examples/CirclingSquare.hs+5−6
@@ -1,11 +1,10 @@
11-- 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.
34--
45-- Requires the SDL package, assuming streamly has already been built, you can
56-- compile it like this:
6−-- stack ghc --package SDL circle-mouse.hs
7−
8−module Streamly.Examples.CirclingSquare where
7+-- stack ghc --package SDL CirclingSquare.hs
98
109import Data.IORef
1110import Graphics.UI.SDL as SDL
@@ -84,8 +83,8 @@ updateDisplay cref = withClock clock refreshRate displaySquare
8483 let t = (fromIntegral time) * speed / 1000000
8584 in display (x + cos t * radius, y + sin t * radius)
8685
87−circlingSquare :: IO ()
88−circlingSquare = do
86+main :: IO ()
87+main = do
8988 sdlInit
9089 cref <- newIORef (0,0)
9190 runStream $ once (updateController cref)
examples/ListDir.hs+5−5
@@ -1,15 +1,15 @@
1−module Streamly.Examples.ListDirRecursive where
2−
31import Path.IO (listDir, getCurrentDir)
42import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
53import Streamly (runStream, coparallely)
64import Streamly.Prelude (once)
75
8−-- | This example demonstrates that there is little difference between regular
6+-- | List the current directory recursively using concurrent processing
7+--
8+-- This example demonstrates that there is little difference between regular
99-- IO code and concurrent streamly code. You can just remove
1010-- 'runStream . coparallely' and this becomes your regular IO code.
11−listDirRecursive :: IO ()
12−listDirRecursive = do
11+main :: IO ()
12+main = do
1313 hSetBuffering stdout LineBuffering
1414 runStream . coparallely $ getCurrentDir >>= readdir
1515 where readdir d = do
examples/MergeSort.hs+2−4
@@ -1,7 +1,5 @@
11{-# LANGUAGE FlexibleContexts #-}
22
3−module Streamly.Examples.MergeSortedStreams where
4−
53import Data.Word
64import System.Random (getStdGen, randoms)
75import Data.List (sort)
@@ -36,7 +34,7 @@ merge a b = do
3634 then (return y) <> merge (return x <> ma) mb
3735 else (return x) <> merge ma (return y <> mb)
3836
39−mergeSortedStreams :: IO ()
40−mergeSortedStreams = do
37+main :: IO ()
38+main = do
4139 xs <- A.toList $ mergeAsync getSorted getSorted
4240 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
22
3+## Running directly using stack
34You can run these examples using `stack` like this:
45
56```
67$ 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
844```
examples/SearchQuery.hs+8−6
@@ -1,13 +1,15 @@
1−module Streamly.Examples.SearchEngineQuery where
2−
31import Streamly
42import Streamly.Prelude (once)
53import Network.HTTP.Simple
64
7−-- Runs three search engine queries in parallel.
8−searchEngineQuery :: IO ()
9−searchEngineQuery = do
10− putStrLn "Using parallel alternative"
5+-- | Runs three search engine queries in parallel and prints the search engine
6+-- names in the fastest first order.
7+--
8+-- Does it twice using two different ways.
9+--
10+main :: IO ()
11+main = do
12+ putStrLn "Using parallel semigroup composition"
1113 runStream . parallely $ google <> bing <> duckduckgo
1214
1315 putStrLn "\nUsing parallel applicative zip"
streamly.cabal+81−40
@@ -35,6 +35,7 @@ cabal-version: >= 1.10
3535extra-source-files:
3636 Changelog.md
3737 README.md
38+ bench.sh
3839 charts/comparative/AllOperationsataGlance.svg
3940 charts/comparative/ComposingPipelineStages.svg
4041 stack-7.10.yaml
@@ -59,6 +60,10 @@ flag examples-sdl
5960 manual: True
6061 default: False
6162
63+-------------------------------------------------------------------------------
64+-- Library
65+-------------------------------------------------------------------------------
66+
6267library
6368 hs-source-dirs: src
6469 other-modules: Streamly.Core
@@ -69,16 +74,6 @@ library
6974 , Streamly.Tutorial
7075 , Streamly
7176
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−
8277 default-language: Haskell2010
8378 ghc-options: -Wall
8479
@@ -95,8 +90,6 @@ library
9590 -Wredundant-constraints
9691 -Wnoncanonical-monad-instances
9792 -Wnoncanonical-monadfail-instances
98− if flag(examples-sdl)
99− cpp-options: -DEXAMPLES_SDL
10093
10194 build-depends: base >= 4.8 && < 5
10295 , atomic-primops >= 0.8 && < 0.9
@@ -114,15 +107,9 @@ library
114107 build-depends:
115108 semigroups >= 0.18 && < 0.19
116109
117− if flag(examples) || flag(examples-sdl)
118− build-Depends:
119− http-conduit >= 2.2.2 && < 2.4
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
110+-------------------------------------------------------------------------------
111+-- Test suites
112+-------------------------------------------------------------------------------
126113
127114test-suite test
128115 type: exitcode-stdio-1.0
@@ -175,6 +162,39 @@ test-suite properties
175162 , hspec >= 2.0 && < 3
176163 default-language: Haskell2010
177164
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+
178198benchmark linear
179199 type: exitcode-stdio-1.0
180200 hs-source-dirs: benchmark
@@ -229,10 +249,6 @@ benchmark nested
229249 , random >= 1.0 && < 2.0
230250 , gauge >= 0.2.1 && < 0.3
231251
232−-------------------------------------------------------------------------------
233−-- Examples
234−-------------------------------------------------------------------------------
235−
236252executable chart-linear
237253 default-language: Haskell2010
238254 hs-source-dirs: benchmark
@@ -259,37 +275,39 @@ executable chart-nested
259275 else
260276 buildable: False
261277
262−executable loops
278+-------------------------------------------------------------------------------
279+-- Examples
280+-------------------------------------------------------------------------------
281+
282+executable SearchQuery
263283 default-language: Haskell2010
264− main-is: loops.hs
284+ main-is: SearchQuery.hs
265285 hs-source-dirs: examples
266286 if flag(examples) || flag(examples-sdl)
267287 buildable: True
268288 build-Depends:
269289 streamly
270− , base >= 4.8 && < 5
290+ , base >= 4.8 && < 5
291+ , http-conduit >= 2.2.2 && < 2.4
271292 else
272293 buildable: False
273294
274−executable nested-loops
295+executable ListDir
275296 default-language: Haskell2010
276− main-is: nested-loops.hs
297+ main-is: ListDir.hs
277298 hs-source-dirs: examples
278299 if flag(examples) || flag(examples-sdl)
279300 buildable: True
280301 build-Depends:
281302 streamly
282− , base >= 4.8 && < 5
283− , random >= 1.0.0 && < 1.2
284− if impl(ghc < 8.0)
285− build-depends:
286− transformers >= 0.4 && < 0.6
303+ , base >= 4.8 && < 5
304+ , path-io >= 0.1.0 && < 1.4
287305 else
288306 buildable: False
289307
290−executable parallel-loops
308+executable MergeSort
291309 default-language: Haskell2010
292− main-is: parallel-loops.hs
310+ main-is: MergeSort.hs
293311 hs-source-dirs: examples
294312 if flag(examples) || flag(examples-sdl)
295313 buildable: True
@@ -297,8 +315,31 @@ executable parallel-loops
297315 streamly
298316 , base >= 4.8 && < 5
299317 , random >= 1.0.0 && < 1.2
300− if impl(ghc < 8.0)
301− build-depends:
302− transformers >= 0.4 && < 0.6
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
327+ build-Depends:
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
303344 else
304345 buildable: False
test/loops.hs−14
@@ -41,10 +41,6 @@ main = do
4141-- Serial (single-threaded) stream generator loops
4242-------------------------------------------------------------------------------
4343
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−
4844 -- Generates a value and then loops. Can be used to generate an infinite
4945 -- stream. Interleaves the generator and the consumer.
5046 loopTail :: Int -> Stream Int
@@ -64,11 +60,6 @@ main = do
6460-- Concurrent (multi-threaded) adaptive demand-based stream generator loops
6561-------------------------------------------------------------------------------
6662
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−
7263 loopTailA :: Int -> Stream Int
7364 loopTailA x = do
7465 once $ putStrLn "LoopTailA..."
@@ -82,8 +73,3 @@ main = do
8273-------------------------------------------------------------------------------
8374-- Parallel (fairly scheduled, multi-threaded) stream generator loops
8475-------------------------------------------------------------------------------
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
1414
1515 where
1616
17+ -- we can just use
18+ -- parallely $ mconcat $ replicate n $ once (...)
1719 loop :: String -> Int -> StreamT IO String
1820 loop name n = do
1921 rnd <- once (randomIO :: IO Int)
test/parallel-loops.hs+15−9
@@ -2,19 +2,25 @@ import Control.Concurrent (myThreadId, threadDelay)
22import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
33import System.Random (randomIO)
44import Streamly
5−import Streamly.Prelude (once)
5+import qualified Streamly.Prelude as S
66
7−main = runStream $ do
8− once $ hSetBuffering stdout LineBuffering
9− x <- loop "A" `parallel` loop "B"
10− once $ myThreadId >>= putStr . show
11− >> putStr " "
12− >> print x
7+main = do
8+ hSetBuffering stdout LineBuffering
9+ runStream $ do
10+ x <- S.take 10 $ loop "A" `parallel` loop "B"
11+ S.once $ myThreadId >>= putStr . show
12+ >> putStr " got "
13+ >> print x
1314
1415 where
1516
17+ -- we can just use
18+ -- parallely $ cycle1 $ once (...)
1619 loop :: String -> Stream (String, Int)
1720 loop name = do
18− once $ threadDelay 1000000
19− rnd <- once (randomIO :: IO Int)
21+ S.once $ threadDelay 1000000
22+ rnd <- S.once (randomIO :: IO Int)
23+ S.once $ myThreadId >>= putStr . show
24+ >> putStr " yielding "
25+ >> print rnd
2026 return (name, rnd) `parallel` loop name