on 5d096df help sign in
94 lines 2.8 kB history raw
1# Frequently Asked Questions
3This document provides idioms or examples to solve common programming
4problems using streamly. To start with please go through [Streamly Quick
5Overview](/docs/User/Tutorials/quick-overview.md) and [`Streamly examples repository`][streamly-examples].
6This document provides additional examples.
8## Distribute and Zip Concurrently
10Transform a stream in multiple ways, generating multiple transformed
11streams and then zip the corresponding elements of each resulting stream
12together to create a single transformed stream.
14Distributing a value to a stream of consumers concurrently:
16```haskell ghci
17{-# LANGUAGE FlexibleContexts #-}
19import Data.Function ((&))
20import qualified Streamly.Data.Fold as Fold
21import qualified Streamly.Data.Stream.Prelude as Stream
23f1 x =
24 Stream.fromList [return . (+ 1), return . (+ 2)] -- Stream of functions
25 & fmap ($ x) -- Stream of lazy actions
26 & Stream.parSequence (Stream.ordered True) -- Evaluate concurrently
27 & Stream.fold Fold.toList -- Fold to list
28```
30Use `parApply` to zip streams concurrently. Here, we zip three singleton
31streams:
33```haskell ghci
35f2 x =
36 let app = Stream.parApply id
37 in (,,)
38 `fmap` Stream.fromEffect (return $ show x)
39 `app` Stream.fromEffect (return $ x + 1)
40 `app` Stream.fromEffect (return $ fromIntegral x / 2)
41 & Stream.fold Fold.one
42```
44Applying a function concurrently to your input stream:
46```haskell ghci
47g f xs =
48 Stream.fromList xs
49 & Stream.parMapM (Stream.ordered True) f
50 & Stream.fold Fold.toList
51```
53You can now use the concurrent map to pipe each element through multiple
54transformations using the distribute/zip operations.
56```haskell docspec
57>>> g f1 [1,2,3,4::Int]
58[[2,3],[3,4],[4,5],[5,6]]
60>>> g f2 [1,2,3,4::Int]
61[Just ("1",2,0.5),Just ("2",3,1.0),Just ("3",4,1.5),Just ("4",5,2.0)]
62```
64Instead of using `parApply` directly, you can use `mkZipType` to
65create a zip Applicative newtype so that you can use the `Applicative`
66instance.
68```haskell
69{-# LANGUAGE UndecidableInstances #-}
70{-# LANGUAGE FlexibleInstances #-}
71{-# LANGUAGE MultiParamTypeClasses #-}
72{-# LANGUAGE TemplateHaskell #-}
74import Streamly.Internal.Data.Stream.TypeGen
76app = parApply id
77$(mkZippingType "ZipConcurrent" "app" True)
78```
80## Sliding Window
82The `writeLastN` fold can be used to create a stream of sliding windows.
84```haskell docspec
85>>> import qualified Streamly.Data.Array as Array
86>>> :{
87 Stream.fromList [1,2,3,4,5::Int]
88& Stream.scan (Array.writeLastN 2)
89& Stream.fold Fold.toList
90:}
91[fromList [],fromList [1],fromList [1,2],fromList [2,3],fromList [3,4],fromList [4,5]]
92```
94Also see the "Streamly.Internal.Data.Fold.Window" module for widnow based folds.