module Streamly.Internal.Data.Refold.Type
(
Refold (..)
, foldl'
, sconcat
, drainBy
, iterate
, lmapM
, rmapM
, append
, take
)
where
import Control.Monad ((>=>))
#if __GLASGOW_HASKELL__ < 804
import Data.Semigroup (Semigroup((<>)))
#endif
import Fusion.Plugin.Types (Fuse(..))
import Streamly.Internal.Data.Fold.Step (Step(..), mapMStep)
import Prelude hiding (take, iterate)
data Refold m c a b =
forall s. Refold (s -> a -> m (Step s b)) (c -> m (Step s b)) (s -> m b)
{-# INLINE foldl' #-}
foldl' :: Monad m => (b -> a -> b) -> Refold m b a b
foldl' :: forall (m :: * -> *) b a.
Monad m =>
(b -> a -> b) -> Refold m b a b
foldl' b -> a -> b
step =
forall (m :: * -> *) c a b s.
(s -> a -> m (Step s b))
-> (c -> m (Step s b)) -> (s -> m b) -> Refold m c a b
Refold
(\b
s a
a -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
Partial forall a b. (a -> b) -> a -> b
$ b -> a -> b
step b
s a
a)
(forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s b. s -> Step s b
Partial)
forall (m :: * -> *) a. Monad m => a -> m a
return
{-# INLINE lmapM #-}
lmapM :: Monad m => (a -> m b) -> Refold m c b r -> Refold m c a r
lmapM :: forall (m :: * -> *) a b c r.
Monad m =>
(a -> m b) -> Refold m c b r -> Refold m c a r
lmapM a -> m b
f (Refold s -> b -> m (Step s r)
step c -> m (Step s r)
inject s -> m r
extract) = forall (m :: * -> *) c a b s.
(s -> a -> m (Step s b))
-> (c -> m (Step s b)) -> (s -> m b) -> Refold m c a b
Refold s -> a -> m (Step s r)
step1 c -> m (Step s r)
inject s -> m r
extract
where
step1 :: s -> a -> m (Step s r)
step1 s
x a
a = a -> m b
f a
a forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> b -> m (Step s r)
step s
x
{-# INLINE rmapM #-}
rmapM :: Monad m => (b -> m c) -> Refold m x a b -> Refold m x a c
rmapM :: forall (m :: * -> *) b c x a.
Monad m =>
(b -> m c) -> Refold m x a b -> Refold m x a c
rmapM b -> m c
f (Refold s -> a -> m (Step s b)
step x -> m (Step s b)
inject s -> m b
extract) = forall (m :: * -> *) c a b s.
(s -> a -> m (Step s b))
-> (c -> m (Step s b)) -> (s -> m b) -> Refold m c a b
Refold s -> a -> m (Step s c)
step1 x -> m (Step s c)
inject1 (s -> m b
extract forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> b -> m c
f)
where
inject1 :: x -> m (Step s c)
inject1 x
x = x -> m (Step s b)
inject x
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) a b s.
Applicative m =>
(a -> m b) -> Step s a -> m (Step s b)
mapMStep b -> m c
f
step1 :: s -> a -> m (Step s c)
step1 s
s a
a = s -> a -> m (Step s b)
step s
s a
a forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) a b s.
Applicative m =>
(a -> m b) -> Step s a -> m (Step s b)
mapMStep b -> m c
f
{-# INLINE drainBy #-}
drainBy :: Monad m => (c -> a -> m b) -> Refold m c a ()
drainBy :: forall (m :: * -> *) c a b.
Monad m =>
(c -> a -> m b) -> Refold m c a ()
drainBy c -> a -> m b
f = forall (m :: * -> *) c a b s.
(s -> a -> m (Step s b))
-> (c -> m (Step s b)) -> (s -> m b) -> Refold m c a b
Refold forall {b}. c -> a -> m (Step c b)
step forall {a} {b}. a -> m (Step a b)
inject forall {m :: * -> *} {p}. Monad m => p -> m ()
extract
where
inject :: a -> m (Step a b)
inject = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s b. s -> Step s b
Partial
step :: c -> a -> m (Step c b)
step c
c a
a = c -> a -> m b
f c
c a
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return (forall s b. s -> Step s b
Partial c
c)
extract :: p -> m ()
extract p
_ = forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# INLINE sconcat #-}
sconcat :: (Monad m, Semigroup a) => Refold m a a a
sconcat :: forall (m :: * -> *) a. (Monad m, Semigroup a) => Refold m a a a
sconcat = forall (m :: * -> *) b a.
Monad m =>
(b -> a -> b) -> Refold m b a b
foldl' forall a. Semigroup a => a -> a -> a
(<>)
{-# INLINE append #-}
append :: Monad m => Refold m x a b -> Refold m b a b -> Refold m x a b
append :: forall (m :: * -> *) x a b.
Monad m =>
Refold m x a b -> Refold m b a b -> Refold m x a b
append (Refold s -> a -> m (Step s b)
step1 x -> m (Step s b)
inject1 s -> m b
extract1) (Refold s -> a -> m (Step s b)
step2 b -> m (Step s b)
inject2 s -> m b
extract2) =
forall (m :: * -> *) c a b s.
(s -> a -> m (Step s b))
-> (c -> m (Step s b)) -> (s -> m b) -> Refold m c a b
Refold Either s s -> a -> m (Step (Either s s) b)
step x -> m (Step (Either s s) b)
inject Either s s -> m b
extract
where
goLeft :: Step a b -> m (Step (Either a s) b)
goLeft Step a b
r = do
case Step a b
r of
Partial a
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
Partial forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left a
s
Done b
b -> do
Step s b
r1 <- b -> m (Step s b)
inject2 b
b
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Step s b
r1 of
Partial s
s -> forall s b. s -> Step s b
Partial forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right s
s
Done b
b1 -> forall s b. b -> Step s b
Done b
b1
inject :: x -> m (Step (Either s s) b)
inject x
x = x -> m (Step s b)
inject1 x
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a}. Step a b -> m (Step (Either a s) b)
goLeft
step :: Either s s -> a -> m (Step (Either s s) b)
step (Left s
s) a
a = s -> a -> m (Step s b)
step1 s
s a
a forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a}. Step a b -> m (Step (Either a s) b)
goLeft
step (Right s
s) a
a = do
Step s b
r <- s -> a -> m (Step s b)
step2 s
s a
a
case Step s b
r of
Partial s
s1 -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
Partial (forall a b. b -> Either a b
Right s
s1)
Done b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Step s b
Done b
b
extract :: Either s s -> m b
extract (Left s
s) = s -> m b
extract1 s
s
extract (Right s
s) = s -> m b
extract2 s
s
iterate :: Monad m => Refold m b a b -> Refold m b a b
iterate :: forall (m :: * -> *) b a.
Monad m =>
Refold m b a b -> Refold m b a b
iterate (Refold s -> a -> m (Step s b)
step1 b -> m (Step s b)
inject1 s -> m b
extract1) =
forall (m :: * -> *) c a b s.
(s -> a -> m (Step s b))
-> (c -> m (Step s b)) -> (s -> m b) -> Refold m c a b
Refold forall {b}. s -> a -> m (Step s b)
step forall {b}. b -> m (Step s b)
inject s -> m b
extract1
where
go :: Step s b -> m (Step s b)
go Step s b
r =
case Step s b
r of
Partial s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
Partial s
s
Done b
b -> b -> m (Step s b)
inject b
b
inject :: b -> m (Step s b)
inject b
x = b -> m (Step s b)
inject1 b
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Step s b -> m (Step s b)
go
step :: s -> a -> m (Step s b)
step s
s a
a = s -> a -> m (Step s b)
step1 s
s a
a forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {b}. Step s b -> m (Step s b)
go
{-# ANN type Tuple'Fused Fuse #-}
data Tuple'Fused a b = Tuple'Fused !a !b deriving Int -> Tuple'Fused a b -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b. (Show a, Show b) => Int -> Tuple'Fused a b -> ShowS
forall a b. (Show a, Show b) => [Tuple'Fused a b] -> ShowS
forall a b. (Show a, Show b) => Tuple'Fused a b -> String
showList :: [Tuple'Fused a b] -> ShowS
$cshowList :: forall a b. (Show a, Show b) => [Tuple'Fused a b] -> ShowS
show :: Tuple'Fused a b -> String
$cshow :: forall a b. (Show a, Show b) => Tuple'Fused a b -> String
showsPrec :: Int -> Tuple'Fused a b -> ShowS
$cshowsPrec :: forall a b. (Show a, Show b) => Int -> Tuple'Fused a b -> ShowS
Show
{-# INLINE take #-}
take :: Monad m => Int -> Refold m x a b -> Refold m x a b
take :: forall (m :: * -> *) x a b.
Monad m =>
Int -> Refold m x a b -> Refold m x a b
take Int
n (Refold s -> a -> m (Step s b)
fstep x -> m (Step s b)
finject s -> m b
fextract) = forall (m :: * -> *) c a b s.
(s -> a -> m (Step s b))
-> (c -> m (Step s b)) -> (s -> m b) -> Refold m c a b
Refold Tuple'Fused Int s -> a -> m (Step (Tuple'Fused Int s) b)
step forall {a}. Num a => x -> m (Step (Tuple'Fused a s) b)
inject forall {a}. Tuple'Fused a s -> m b
extract
where
inject :: x -> m (Step (Tuple'Fused a s) b)
inject x
x = do
Step s b
res <- x -> m (Step s b)
finject x
x
case Step s b
res of
Partial s
s ->
if Int
n forall a. Ord a => a -> a -> Bool
> Int
0
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
Partial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple'Fused a b
Tuple'Fused a
0 s
s
else forall s b. b -> Step s b
Done forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract s
s
Done b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Step s b
Done b
b
step :: Tuple'Fused Int s -> a -> m (Step (Tuple'Fused Int s) b)
step (Tuple'Fused Int
i s
r) a
a = do
Step s b
res <- s -> a -> m (Step s b)
fstep s
r a
a
case Step s b
res of
Partial s
sres -> do
let i1 :: Int
i1 = Int
i forall a. Num a => a -> a -> a
+ Int
1
s1 :: Tuple'Fused Int s
s1 = forall a b. a -> b -> Tuple'Fused a b
Tuple'Fused Int
i1 s
sres
if Int
i1 forall a. Ord a => a -> a -> Bool
< Int
n
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
Partial Tuple'Fused Int s
s1
else forall s b. b -> Step s b
Done forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract s
sres
Done b
bres -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Step s b
Done b
bres
extract :: Tuple'Fused a s -> m b
extract (Tuple'Fused a
_ s
r) = s -> m b
fextract s
r