{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving#-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Streamly.Streams.Zip
(
K.zipWith
, K.zipWithM
, zipAsyncWith
, zipAsyncWithM
, ZipSerialM
, ZipSerial
, ZipStream
, zipSerially
, zipping
, ZipAsyncM
, ZipAsync
, zipAsyncly
, zippingAsync
)
where
import Control.Applicative (liftA2)
import Control.DeepSeq (NFData(..), NFData1(..), rnf1)
import Data.Functor.Identity (Identity, runIdentity)
import Data.Foldable (fold)
import Data.Semigroup (Semigroup(..))
import GHC.Exts (IsList(..), IsString(..))
import Text.Read (Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec,
readListPrecDefault)
import Prelude hiding (map, repeat, zipWith)
import Streamly.Streams.StreamK (IsStream(..), Stream, mkStream, foldStream)
import Streamly.Streams.Async (mkAsync')
import Streamly.Streams.Serial (map)
import Streamly.SVar (MonadAsync, adaptState)
import qualified Streamly.Streams.Prelude as P
import qualified Streamly.Streams.StreamK as K
#include "Instances.hs"
newtype ZipSerialM m a = ZipSerialM {getZipSerialM :: Stream m a}
deriving (Semigroup, Monoid)
{-# DEPRECATED ZipStream "Please use 'ZipSerialM' instead." #-}
type ZipStream = ZipSerialM
type ZipSerial = ZipSerialM IO
zipSerially :: IsStream t => ZipSerialM m a -> t m a
zipSerially = K.adapt
{-# DEPRECATED zipping "Please use zipSerially instead." #-}
zipping :: IsStream t => ZipSerialM m a -> t m a
zipping = zipSerially
consMZip :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
consMZip m ms = fromStream $ K.consMStream m (toStream ms)
instance IsStream ZipSerialM where
toStream = getZipSerialM
fromStream = ZipSerialM
{-# INLINE consM #-}
{-# SPECIALIZE consM :: IO a -> ZipSerialM IO a -> ZipSerialM IO a #-}
consM :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
consM = consMZip
{-# INLINE (|:) #-}
{-# SPECIALIZE (|:) :: IO a -> ZipSerialM IO a -> ZipSerialM IO a #-}
(|:) :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
(|:) = consMZip
LIST_INSTANCES(ZipSerialM)
instance Monad m => Functor (ZipSerialM m) where
fmap = map
instance Monad m => Applicative (ZipSerialM m) where
pure = ZipSerialM . K.repeat
(<*>) = K.zipWith id
FOLDABLE_INSTANCE(ZipSerialM)
TRAVERSABLE_INSTANCE(ZipSerialM)
{-# INLINABLE zipAsyncWith #-}
zipAsyncWith :: (IsStream t, MonadAsync m)
=> (a -> b -> c) -> t m a -> t m b -> t m c
zipAsyncWith f m1 m2 = mkStream $ \st stp sng yld -> do
ma <- mkAsync' (adaptState st) m1
mb <- mkAsync' (adaptState st) m2
foldStream st stp sng yld (K.zipWith f ma mb)
{-# INLINABLE zipAsyncWithM #-}
zipAsyncWithM :: (IsStream t, MonadAsync m)
=> (a -> b -> m c) -> t m a -> t m b -> t m c
zipAsyncWithM f m1 m2 = mkStream $ \st stp sng yld -> do
ma <- mkAsync' (adaptState st) m1
mb <- mkAsync' (adaptState st) m2
foldStream st stp sng yld (K.zipWithM f ma mb)
newtype ZipAsyncM m a = ZipAsyncM {getZipAsyncM :: Stream m a}
deriving (Semigroup, Monoid)
type ZipAsync = ZipAsyncM IO
zipAsyncly :: IsStream t => ZipAsyncM m a -> t m a
zipAsyncly = K.adapt
{-# DEPRECATED zippingAsync "Please use zipAsyncly instead." #-}
zippingAsync :: IsStream t => ZipAsyncM m a -> t m a
zippingAsync = zipAsyncly
consMZipAsync :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
consMZipAsync m ms = fromStream $ K.consMStream m (toStream ms)
instance IsStream ZipAsyncM where
toStream = getZipAsyncM
fromStream = ZipAsyncM
{-# INLINE consM #-}
{-# SPECIALIZE consM :: IO a -> ZipAsyncM IO a -> ZipAsyncM IO a #-}
consM :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
consM = consMZipAsync
{-# INLINE (|:) #-}
{-# SPECIALIZE (|:) :: IO a -> ZipAsyncM IO a -> ZipAsyncM IO a #-}
(|:) :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
(|:) = consMZipAsync
instance Monad m => Functor (ZipAsyncM m) where
fmap = map
instance MonadAsync m => Applicative (ZipAsyncM m) where
pure = ZipAsyncM . K.repeat
m1 <*> m2 = zipAsyncWith id m1 m2