module Streamly.Internal.Data.Fold.Step
(
Step (..)
, mapMStep
, chainStepM
)
where
import Data.Bifunctor (Bifunctor(..))
import Fusion.Plugin.Types (Fuse(..))
{-# ANN type Step Fuse #-}
data Step s b
= Partial !s
| Done !b
instance Bifunctor Step where
{-# INLINE bimap #-}
bimap :: forall a b c d. (a -> b) -> (c -> d) -> Step a c -> Step b d
bimap a -> b
f c -> d
_ (Partial a
a) = b -> Step b d
forall s b. s -> Step s b
Partial (a -> b
f a
a)
bimap a -> b
_ c -> d
g (Done c
b) = d -> Step b d
forall s b. b -> Step s b
Done (c -> d
g c
b)
{-# INLINE first #-}
first :: forall a b c. (a -> b) -> Step a c -> Step b c
first a -> b
f (Partial a
a) = b -> Step b c
forall s b. s -> Step s b
Partial (a -> b
f a
a)
first a -> b
_ (Done c
x) = c -> Step b c
forall s b. b -> Step s b
Done c
x
{-# INLINE second #-}
second :: forall b c a. (b -> c) -> Step a b -> Step a c
second b -> c
_ (Partial a
x) = a -> Step a c
forall s b. s -> Step s b
Partial a
x
second b -> c
f (Done b
a) = c -> Step a c
forall s b. b -> Step s b
Done (b -> c
f b
a)
instance Functor (Step s) where
{-# INLINE fmap #-}
fmap :: forall a b. (a -> b) -> Step s a -> Step s b
fmap = (a -> b) -> Step s a -> Step s b
forall b c a. (b -> c) -> Step a b -> Step a c
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second
{-# INLINE mapMStep #-}
mapMStep :: Applicative m => (a -> m b) -> Step s a -> m (Step s b)
mapMStep :: forall (m :: * -> *) a b s.
Applicative m =>
(a -> m b) -> Step s a -> m (Step s b)
mapMStep a -> m b
f Step s a
res =
case Step s a
res of
Partial s
s -> Step s b -> m (Step s b)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step s b -> m (Step s b)) -> Step s b -> m (Step s b)
forall a b. (a -> b) -> a -> b
$ s -> Step s b
forall s b. s -> Step s b
Partial s
s
Done a
b -> b -> Step s b
forall s b. b -> Step s b
Done (b -> Step s b) -> m b -> m (Step s b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> m b
f a
b
{-# INLINE chainStepM #-}
chainStepM :: Applicative m =>
(s1 -> m s2) -> (a -> m (Step s2 b)) -> Step s1 a -> m (Step s2 b)
chainStepM :: forall (m :: * -> *) s1 s2 a b.
Applicative m =>
(s1 -> m s2) -> (a -> m (Step s2 b)) -> Step s1 a -> m (Step s2 b)
chainStepM s1 -> m s2
f a -> m (Step s2 b)
_ (Partial s1
s) = s2 -> Step s2 b
forall s b. s -> Step s b
Partial (s2 -> Step s2 b) -> m s2 -> m (Step s2 b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s1 -> m s2
f s1
s
chainStepM s1 -> m s2
_ a -> m (Step s2 b)
g (Done a
b) = a -> m (Step s2 b)
g a
b