on da36a01 help sign in
114 lines 3.6 kB history raw
1{-# LANGUAGE StandaloneDeriving #-}
2{-# LANGUAGE UndecidableInstances #-}
4-- |
5-- Module : Streamly.Internal.Data.Stream.Zip
6-- Copyright : (c) 2017 Composewell Technologies
7--
8-- License : BSD3
9-- Maintainer : streamly@composewell.com
10-- Stability : experimental
11-- Portability : GHC
12--
13-- To run examples in this module:
14--
15-- >>> import qualified Streamly.Data.Fold as Fold
16-- >>> import qualified Streamly.Data.Stream as Stream
17-- >>> import qualified Streamly.Internal.Data.Stream.Zip as Stream
18--
19module Streamly.Internal.Data.Stream.Zip
20 (
21 ZipStream (..)
22 , ZipSerialM
23 , ZipSerial
24 , zipWithD
25 , zipWithMD
26 )
27where
29import Control.DeepSeq (NFData(..), NFData1(..))
30import Data.Functor.Identity (Identity(..))
31import GHC.Exts (IsList(..), IsString(..))
32import Streamly.Internal.Data.Stream.Type (Stream, toStreamD, fromStreamD)
33import Text.Read
34 ( Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec
35 , readListPrecDefault)
37import qualified Streamly.Internal.Data.Stream as Stream
38import qualified Streamly.Internal.Data.Stream.StreamD as D
40-- $setup
41-- >>> import qualified Streamly.Data.Fold as Fold
42-- >>> import qualified Streamly.Data.Stream as Stream
43-- >>> import qualified Streamly.Internal.Data.Stream.Zip as Stream
45{-# INLINE zipWithMD #-}
46zipWithMD :: Monad m =>
47 (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
48zipWithMD f m1 m2 =
49 fromStreamD $ D.zipWithM f (toStreamD m1) (toStreamD m2)
51{-# INLINE zipWithD #-}
52zipWithD :: Monad m
53 => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
54zipWithD f = zipWithMD (\a b -> return (f a b))
56------------------------------------------------------------------------------
57-- Serially Zipping Streams
58------------------------------------------------------------------------------
60-- | For 'ZipStream':
61--
62-- @
63-- (<>) = 'Streamly.Data.Stream.append'
64-- (<*>) = 'Streamly.Data.Stream.zipWith' id
65-- @
66--
67-- Applicative evaluates the streams being zipped serially:
68--
69-- >>> s1 = Stream.ZipStream $ Stream.fromFoldable [1, 2]
70-- >>> s2 = Stream.ZipStream $ Stream.fromFoldable [3, 4]
71-- >>> s3 = Stream.ZipStream $ Stream.fromFoldable [5, 6]
72-- >>> s = (,,) <$> s1 <*> s2 <*> s3
73-- >>> Stream.fold Fold.toList (Stream.getZipStream s)
74-- [(1,3,5),(2,4,6)]
75--
76-- /Since: 0.2.0 ("Streamly")/
77--
78-- @since 0.8.0
79newtype ZipStream m a = ZipStream {getZipStream :: Stream m a}
80 deriving (Functor, Semigroup, Monoid)
82deriving instance NFData a => NFData (ZipStream Identity a)
83deriving instance NFData1 (ZipStream Identity)
84deriving instance IsList (ZipStream Identity a)
85deriving instance (a ~ Char) => IsString (ZipStream Identity a)
86deriving instance Eq a => Eq (ZipStream Identity a)
87deriving instance Ord a => Ord (ZipStream Identity a)
88deriving instance (Foldable m, Monad m) => Foldable (ZipStream m)
89deriving instance Traversable (ZipStream Identity)
91instance Show a => Show (ZipStream Identity a) where
92 showsPrec p dl = showParen (p > 10) $
93 showString "fromList " . shows (toList dl)
95instance Read a => Read (ZipStream Identity a) where
96 readPrec = parens $ prec 10 $ do
97 Ident "fromList" <- lexP
98 fromList <$> readPrec
99 readListPrec = readListPrecDefault
101type ZipSerialM = ZipStream
103-- | An IO stream whose applicative instance zips streams serially.
104--
105-- /Since: 0.2.0 ("Streamly")/
106--
107-- @since 0.8.0
108type ZipSerial = ZipSerialM IO
110instance Monad m => Applicative (ZipStream m) where
111 pure = ZipStream . Stream.repeat
113 {-# INLINE (<*>) #-}
114 ZipStream m1 <*> ZipStream m2 = ZipStream $ zipWithD id m1 m2