@@ -0,0 +1,47 @@
1+{-# LANGUAGE UndecidableInstances #-}
2+-- |
3+-- Module : Streamly.Internal.Data.Stream.Concurrent
4+-- Copyright : (c) 2017 Composewell Technologies
5+-- License : BSD-3-Clause
6+-- Maintainer : streamly@composewell.com
7+-- Stability : experimental
8+-- Portability : GHC
9+--
10+-- To run examples in this module:
11+--
12+-- >>> import qualified Streamly.Prelude as Stream
13+--
14+module Streamly.Internal.Data.Stream.Zip.Concurrent
15+ (
16+ ZipConcurrent (..)
17+ )
18+where
19+
20+import Streamly.Internal.Data.Stream (Stream)
21+import Streamly.Internal.Data.Stream.Concurrent (MonadAsync, zipWith)
22+
23+import qualified Streamly.Internal.Data.Stream as Stream (repeat)
24+import Prelude hiding (map, repeat, zipWith)
25+
26+-- $setup
27+-- >>> import qualified Streamly.Internal.Data.Stream as Stream
28+-- >>> import qualified Streamly.Data.Fold as Fold
29+--
30+
31+newtype ZipConcurrent m a = ZipConcurrent {getZipConcurrent :: Stream m a}
32+ deriving (Functor)
33+
34+-- | An IO stream whose applicative instance zips streams concurrently.
35+--
36+-- >>> s = ZipConcurrent $ Stream.fromList [1, 2, 3]
37+-- >>> x = (,,) <$> s <*> s <*> s
38+-- >>> Stream.fold Fold.toList (getZipConcurrent x)
39+-- [(1,1,1),(2,2,2),(3,3,3)]
40+--
41+-- @since 0.9.0
42+
43+instance MonadAsync m => Applicative (ZipConcurrent m) where
44+ pure = ZipConcurrent . Stream.repeat
45+
46+ {-# INLINE (<*>) #-}
47+ ZipConcurrent m1 <*> ZipConcurrent m2 = ZipConcurrent $ zipWith id m1 m2