{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
#include "inline.hs"
module Streamly.Internal.Data.Stream.StreamDK
(
Stream
, Step (..)
, nil
, cons
, consM
, unfoldr
, unfoldrM
, replicateM
, uncons
, foldrS
, drain
)
where
import Streamly.Internal.Data.Stream.StreamDK.Type (Stream(..), Step(..))
nil :: Monad m => Stream m a
nil = Stream $ return Stop
{-# INLINE_NORMAL cons #-}
cons :: Monad m => a -> Stream m a -> Stream m a
cons x xs = Stream $ return $ Yield x xs
consM :: Monad m => m a -> Stream m a -> Stream m a
consM eff xs = Stream $ eff >>= \x -> return $ Yield x xs
unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
unfoldrM next state = Stream (step' state)
where
step' st = do
r <- next st
return $ case r of
Just (x, s) -> Yield x (Stream (step' s))
Nothing -> Stop
{-# INLINE unfoldr #-}
unfoldr :: Monad m => (b -> Maybe (a, b)) -> b -> Stream m a
unfoldr next s0 = build $ \yld stp ->
let go s =
case next s of
Just (a, b) -> yld a (go b)
Nothing -> stp
in go s0
replicateM :: Monad m => Int -> a -> Stream m a
replicateM n x = Stream (step n)
where
step i = return $
if i <= 0
then Stop
else Yield x (Stream (step (i - 1)))
uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
uncons (Stream step) = do
r <- step
return $ case r of
Yield x xs -> Just (x, xs)
Stop -> Nothing
{-# INLINE_NORMAL foldrS #-}
foldrS :: Monad m
=> (a -> Stream m b -> Stream m b)
-> Stream m b
-> Stream m a
-> Stream m b
foldrS f streamb = go
where
go (Stream stepa) = Stream $ do
r <- stepa
case r of
Yield x xs -> let Stream step = f x (go xs) in step
Stop -> let Stream step = streamb in step
{-# INLINE_LATE foldrM #-}
foldrM :: Monad m => (a -> m b -> m b) -> m b -> Stream m a -> m b
foldrM fstep acc ys = go ys
where
go (Stream step) = do
r <- step
case r of
Yield x xs -> fstep x (go xs)
Stop -> acc
{-# INLINE_NORMAL build #-}
build :: Monad m
=> forall a. (forall b. (a -> b -> b) -> b -> b) -> Stream m a
build g = g cons nil
{-# RULES
"foldrM/build" forall k z (g :: forall b. (a -> b -> b) -> b -> b).
foldrM k z (build g) = g k z #-}
{-# INLINE drain #-}
drain :: Monad m => Stream m a -> m ()
drain = foldrM (\_ xs -> xs) (return ())