Move examples from Streamly module to examples dir

This commit is contained in:
Harendra Kumar 2018-05-04 01:27:22 +05:30
parent f3dbbde613
commit c5f97f0e3b
11 changed files with 178 additions and 110 deletions

View File

@ -121,7 +121,7 @@ matrix:
# Note COVERALLS (hpc-coveralls) works only with cabal build. # Note COVERALLS (hpc-coveralls) works only with cabal build.
# For this to succeed you have to add your project to coveralls.io first # For this to succeed you have to add your project to coveralls.io first
- env: BUILD=cabal CABALVER=2.0 GHCVER=8.2.2 COVERALLS_OPTIONS="--coverage-mode=StrictlyFullLines --exclude-dir=test test properties" - 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"
addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2], sources: [hvr-ghc]}} addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2], sources: [hvr-ghc]}}
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------

View File

@ -3,8 +3,6 @@
-- This example is adapted from Gabriel Gonzalez's pipes-concurrency package. -- This example is adapted from Gabriel Gonzalez's pipes-concurrency package.
-- https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html -- https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html
module Streamly.Examples.AcidRainGame where
import Streamly import Streamly
import Control.Concurrent (threadDelay) import Control.Concurrent (threadDelay)
import Control.Monad (when) import Control.Monad (when)
@ -38,8 +36,8 @@ game = do
when (h <= 0) $ fail "You die!" when (h <= 0) $ fail "You die!"
liftIO $ putStrLn $ "Health = " ++ show h liftIO $ putStrLn $ "Health = " ++ show h
acidRainGame :: IO () main :: IO ()
acidRainGame = do main = do
putStrLn "Your health is deteriorating due to acid rain,\ putStrLn "Your health is deteriorating due to acid rain,\
\ type \"potion\" or \"quit\"" \ type \"potion\" or \"quit\""
_ <- runStateT (runStream game) 60 _ <- runStateT (runStream game) 60

View File

@ -1,11 +1,10 @@
-- Adapted from the Yampa package. -- Adapted from the Yampa package.
-- Displays a square moving in a circle. To move the position drag the mouse. -- Displays a square moving in a circle. To move the position drag it with the
-- mouse.
-- --
-- Requires the SDL package, assuming streamly has already been built, you can -- Requires the SDL package, assuming streamly has already been built, you can
-- compile it like this: -- compile it like this:
-- stack ghc --package SDL circle-mouse.hs -- stack ghc --package SDL CirclingSquare.hs
module Streamly.Examples.CirclingSquare where
import Data.IORef import Data.IORef
import Graphics.UI.SDL as SDL import Graphics.UI.SDL as SDL
@ -84,8 +83,8 @@ updateDisplay cref = withClock clock refreshRate displaySquare
let t = (fromIntegral time) * speed / 1000000 let t = (fromIntegral time) * speed / 1000000
in display (x + cos t * radius, y + sin t * radius) in display (x + cos t * radius, y + sin t * radius)
circlingSquare :: IO () main :: IO ()
circlingSquare = do main = do
sdlInit sdlInit
cref <- newIORef (0,0) cref <- newIORef (0,0)
runStream $ once (updateController cref) runStream $ once (updateController cref)

View File

@ -1,15 +1,15 @@
module Streamly.Examples.ListDirRecursive where
import Path.IO (listDir, getCurrentDir) import Path.IO (listDir, getCurrentDir)
import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering)) import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
import Streamly (runStream, coparallely) import Streamly (runStream, coparallely)
import Streamly.Prelude (once) import Streamly.Prelude (once)
-- | This example demonstrates that there is little difference between regular -- | List the current directory recursively using concurrent processing
--
-- This example demonstrates that there is little difference between regular
-- IO code and concurrent streamly code. You can just remove -- IO code and concurrent streamly code. You can just remove
-- 'runStream . coparallely' and this becomes your regular IO code. -- 'runStream . coparallely' and this becomes your regular IO code.
listDirRecursive :: IO () main :: IO ()
listDirRecursive = do main = do
hSetBuffering stdout LineBuffering hSetBuffering stdout LineBuffering
runStream . coparallely $ getCurrentDir >>= readdir runStream . coparallely $ getCurrentDir >>= readdir
where readdir d = do where readdir d = do

View File

@ -1,7 +1,5 @@
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
module Streamly.Examples.MergeSortedStreams where
import Data.Word import Data.Word
import System.Random (getStdGen, randoms) import System.Random (getStdGen, randoms)
import Data.List (sort) import Data.List (sort)
@ -36,7 +34,7 @@ merge a b = do
then (return y) <> merge (return x <> ma) mb then (return y) <> merge (return x <> ma) mb
else (return x) <> merge ma (return y <> mb) else (return x) <> merge ma (return y <> mb)
mergeSortedStreams :: IO () main :: IO ()
mergeSortedStreams = do main = do
xs <- A.toList $ mergeAsync getSorted getSorted xs <- A.toList $ mergeAsync getSorted getSorted
putStrLn $ show $ length xs putStrLn $ show $ length xs

View File

@ -1,8 +1,44 @@
For better examples see the Streamly.Examples module. # Running The Examples
## Running directly using stack
You can run these examples using `stack` like this: You can run these examples using `stack` like this:
``` ```
$ stack build $ stack build
$ stack loop.hs $ stack AcidRain.hs
```
Note: This method may not work for `CirclingSquare.hs` SDL animation example.
## Build and run
Build the library with the `examples` flag on e.g.
```
stack build --flag streamly:examples
cabal new-build --flags examples
```
Then run the executables, for example:
```
stack exec AcidRain
```
The executable name are the same as the filenames.
## Running the SDL animation example
To include the SDL examples as well build with `examples-sdl` flag:
```
stack build --flag streamly:examples-sdl
cabal new-build --flags examples-sdl
```
Make sure that you have the SDL OS package installed on your system and the
headers are visible to Haskell build tool.
```
stack exec CirclingSquare
``` ```

View File

@ -1,13 +1,15 @@
module Streamly.Examples.SearchEngineQuery where
import Streamly import Streamly
import Streamly.Prelude (once) import Streamly.Prelude (once)
import Network.HTTP.Simple import Network.HTTP.Simple
-- Runs three search engine queries in parallel. -- | Runs three search engine queries in parallel and prints the search engine
searchEngineQuery :: IO () -- names in the fastest first order.
searchEngineQuery = do --
putStrLn "Using parallel alternative" -- Does it twice using two different ways.
--
main :: IO ()
main = do
putStrLn "Using parallel semigroup composition"
runStream . parallely $ google <> bing <> duckduckgo runStream . parallely $ google <> bing <> duckduckgo
putStrLn "\nUsing parallel applicative zip" putStrLn "\nUsing parallel applicative zip"

View File

@ -35,6 +35,7 @@ cabal-version: >= 1.10
extra-source-files: extra-source-files:
Changelog.md Changelog.md
README.md README.md
bench.sh
charts/comparative/AllOperationsataGlance.svg charts/comparative/AllOperationsataGlance.svg
charts/comparative/ComposingPipelineStages.svg charts/comparative/ComposingPipelineStages.svg
stack-7.10.yaml stack-7.10.yaml
@ -59,6 +60,10 @@ flag examples-sdl
manual: True manual: True
default: False default: False
-------------------------------------------------------------------------------
-- Library
-------------------------------------------------------------------------------
library library
hs-source-dirs: src hs-source-dirs: src
other-modules: Streamly.Core other-modules: Streamly.Core
@ -69,16 +74,6 @@ library
, Streamly.Tutorial , Streamly.Tutorial
, Streamly , Streamly
if flag(examples) || flag(examples-sdl)
exposed-modules: Streamly.Examples
, Streamly.Examples.SearchEngineQuery
, Streamly.Examples.ListDirRecursive
, Streamly.Examples.MergeSortedStreams
, Streamly.Examples.AcidRainGame
if flag(examples-sdl)
exposed-modules: Streamly.Examples.CirclingSquare
default-language: Haskell2010 default-language: Haskell2010
ghc-options: -Wall ghc-options: -Wall
@ -95,8 +90,6 @@ library
-Wredundant-constraints -Wredundant-constraints
-Wnoncanonical-monad-instances -Wnoncanonical-monad-instances
-Wnoncanonical-monadfail-instances -Wnoncanonical-monadfail-instances
if flag(examples-sdl)
cpp-options: -DEXAMPLES_SDL
build-depends: base >= 4.8 && < 5 build-depends: base >= 4.8 && < 5
, atomic-primops >= 0.8 && < 0.9 , atomic-primops >= 0.8 && < 0.9
@ -114,15 +107,9 @@ library
build-depends: build-depends:
semigroups >= 0.18 && < 0.19 semigroups >= 0.18 && < 0.19
if flag(examples) || flag(examples-sdl) -------------------------------------------------------------------------------
build-Depends: -- Test suites
http-conduit >= 2.2.2 && < 2.4 -------------------------------------------------------------------------------
, path-io >= 0.1.0 && < 1.4
, random >= 1.0.0 && < 1.2
if flag(examples-sdl)
build-Depends:
SDL >= 0.6.5 && < 0.7
test-suite test test-suite test
type: exitcode-stdio-1.0 type: exitcode-stdio-1.0
@ -175,6 +162,39 @@ test-suite properties
, hspec >= 2.0 && < 3 , hspec >= 2.0 && < 3
default-language: Haskell2010 default-language: Haskell2010
test-suite loops
type: exitcode-stdio-1.0
default-language: Haskell2010
main-is: loops.hs
hs-source-dirs: test
build-Depends:
streamly
, base >= 4.8 && < 5
test-suite nested-loops
type: exitcode-stdio-1.0
default-language: Haskell2010
main-is: nested-loops.hs
hs-source-dirs: test
build-Depends:
streamly
, base >= 4.8 && < 5
, random >= 1.0.0 && < 1.2
test-suite parallel-loops
type: exitcode-stdio-1.0
default-language: Haskell2010
main-is: parallel-loops.hs
hs-source-dirs: test
build-Depends:
streamly
, base >= 4.8 && < 5
, random >= 1.0.0 && < 1.2
-------------------------------------------------------------------------------
-- Benchmarks
-------------------------------------------------------------------------------
benchmark linear benchmark linear
type: exitcode-stdio-1.0 type: exitcode-stdio-1.0
hs-source-dirs: benchmark hs-source-dirs: benchmark
@ -229,10 +249,6 @@ benchmark nested
, random >= 1.0 && < 2.0 , random >= 1.0 && < 2.0
, gauge >= 0.2.1 && < 0.3 , gauge >= 0.2.1 && < 0.3
-------------------------------------------------------------------------------
-- Examples
-------------------------------------------------------------------------------
executable chart-linear executable chart-linear
default-language: Haskell2010 default-language: Haskell2010
hs-source-dirs: benchmark hs-source-dirs: benchmark
@ -259,46 +275,71 @@ executable chart-nested
else else
buildable: False buildable: False
executable loops -------------------------------------------------------------------------------
-- Examples
-------------------------------------------------------------------------------
executable SearchQuery
default-language: Haskell2010 default-language: Haskell2010
main-is: loops.hs main-is: SearchQuery.hs
hs-source-dirs: examples hs-source-dirs: examples
if flag(examples) || flag(examples-sdl) if flag(examples) || flag(examples-sdl)
buildable: True
build-Depends:
streamly
, base >= 4.8 && < 5
, http-conduit >= 2.2.2 && < 2.4
else
buildable: False
executable ListDir
default-language: Haskell2010
main-is: ListDir.hs
hs-source-dirs: examples
if flag(examples) || flag(examples-sdl)
buildable: True
build-Depends:
streamly
, base >= 4.8 && < 5
, path-io >= 0.1.0 && < 1.4
else
buildable: False
executable MergeSort
default-language: Haskell2010
main-is: MergeSort.hs
hs-source-dirs: examples
if flag(examples) || flag(examples-sdl)
buildable: True
build-Depends:
streamly
, base >= 4.8 && < 5
, random >= 1.0.0 && < 1.2
else
buildable: False
executable AcidRain
default-language: Haskell2010
main-is: AcidRain.hs
hs-source-dirs: examples
if flag(examples) || flag(examples-sdl)
buildable: True
build-Depends:
streamly
, base >= 4.8 && < 5
, mtl >= 2.2 && < 3
else
buildable: False
executable CirclingSquare
default-language: Haskell2010
main-is: CirclingSquare.hs
hs-source-dirs: examples
if flag(examples-sdl)
buildable: True buildable: True
build-Depends: build-Depends:
streamly streamly
, base >= 4.8 && < 5 , base >= 4.8 && < 5
else , SDL >= 0.6.5 && < 0.7
buildable: False
executable nested-loops
default-language: Haskell2010
main-is: nested-loops.hs
hs-source-dirs: examples
if flag(examples) || flag(examples-sdl)
buildable: True
build-Depends:
streamly
, base >= 4.8 && < 5
, random >= 1.0.0 && < 1.2
if impl(ghc < 8.0)
build-depends:
transformers >= 0.4 && < 0.6
else
buildable: False
executable parallel-loops
default-language: Haskell2010
main-is: parallel-loops.hs
hs-source-dirs: examples
if flag(examples) || flag(examples-sdl)
buildable: True
build-Depends:
streamly
, base >= 4.8 && < 5
, random >= 1.0.0 && < 1.2
if impl(ghc < 8.0)
build-depends:
transformers >= 0.4 && < 0.6
else else
buildable: False buildable: False

View File

@ -41,10 +41,6 @@ main = do
-- Serial (single-threaded) stream generator loops -- Serial (single-threaded) stream generator loops
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- In a <> composition the action on the left is executed and only after it
-- finished then the action on the right is executed. In other words the
-- actions are run serially.
-- Generates a value and then loops. Can be used to generate an infinite -- Generates a value and then loops. Can be used to generate an infinite
-- stream. Interleaves the generator and the consumer. -- stream. Interleaves the generator and the consumer.
loopTail :: Int -> Stream Int loopTail :: Int -> Stream Int
@ -64,11 +60,6 @@ main = do
-- Concurrent (multi-threaded) adaptive demand-based stream generator loops -- Concurrent (multi-threaded) adaptive demand-based stream generator loops
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- In a <| composition the action on the left is executed first. However,
-- if it is not fast enough to generate results at the consumer's speed
-- then the action on the right is also spawned concurrently. In other
-- words, both actions may run concurrently based on the need.
loopTailA :: Int -> Stream Int loopTailA :: Int -> Stream Int
loopTailA x = do loopTailA x = do
once $ putStrLn "LoopTailA..." once $ putStrLn "LoopTailA..."
@ -82,8 +73,3 @@ main = do
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Parallel (fairly scheduled, multi-threaded) stream generator loops -- Parallel (fairly scheduled, multi-threaded) stream generator loops
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- In a <|> composition both actions are run concurrently in a fair
-- manner, no one action is preferred over another. Both actions are
-- spawned right away in their own independent threads. In other words, the
-- actions will run concurrently.

View File

@ -14,6 +14,8 @@ main = runStream $ do
where where
-- we can just use
-- parallely $ mconcat $ replicate n $ once (...)
loop :: String -> Int -> StreamT IO String loop :: String -> Int -> StreamT IO String
loop name n = do loop name n = do
rnd <- once (randomIO :: IO Int) rnd <- once (randomIO :: IO Int)

View File

@ -2,19 +2,25 @@ import Control.Concurrent (myThreadId, threadDelay)
import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering)) import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
import System.Random (randomIO) import System.Random (randomIO)
import Streamly import Streamly
import Streamly.Prelude (once) import qualified Streamly.Prelude as S
main = runStream $ do main = do
once $ hSetBuffering stdout LineBuffering hSetBuffering stdout LineBuffering
x <- loop "A" `parallel` loop "B" runStream $ do
once $ myThreadId >>= putStr . show x <- S.take 10 $ loop "A" `parallel` loop "B"
>> putStr " " S.once $ myThreadId >>= putStr . show
>> print x >> putStr " got "
>> print x
where where
-- we can just use
-- parallely $ cycle1 $ once (...)
loop :: String -> Stream (String, Int) loop :: String -> Stream (String, Int)
loop name = do loop name = do
once $ threadDelay 1000000 S.once $ threadDelay 1000000
rnd <- once (randomIO :: IO Int) rnd <- S.once (randomIO :: IO Int)
S.once $ myThreadId >>= putStr . show
>> putStr " yielding "
>> print rnd
return (name, rnd) `parallel` loop name return (name, rnd) `parallel` loop name