{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE LinearTypes #-}
{-# LANGUAGE QualifiedDo #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wno-name-shadowing #-}

module Streaming.Linear
  ( -- $stream
    module Streaming.Linear.Internal.Type,

    -- * Constructing a 'Stream' on a given functor
    yields,
    effect,
    wrap,
    replicates,
    replicatesM,
    unfold,
    untilJust,
    streamBuild,
    delays,

    -- * Transforming streams
    maps,
    mapsPost,
    mapsM,
    mapsMPost,
    mapped,
    mappedPost,
    hoistUnexposed,
    groups,

    -- * Inspecting a stream
    inspect,

    -- * Splitting and joining 'Stream's
    splitsAt,
    chunksOf,
    concats,
    intercalates,

    -- * Zipping, unzipping, separating and unseparating streams
    unzips,
    separate,
    unseparate,
    decompose,
    expand,
    expandPost,

    -- * Eliminating a 'Stream'
    mapsM_,
    run,
    streamFold,
    iterTM,
    iterT,
    destroy,
  )
where

import Control.Concurrent (threadDelay)
import qualified Control.Functor.Linear as Control
import Data.Functor.Compose
import qualified Data.Functor.Linear as Data
import Data.Functor.Sum
import Data.Unrestricted.Linear
import GHC.Stack
import Prelude.Linear (($), (&), (.))
import Streaming.Linear.Internal.Process (destroyExposed)
import Streaming.Linear.Internal.Type
import qualified Streaming.Prelude.Linear as Stream
import System.IO.Linear
import Prelude
  ( Double,
    Either (..),
    Int,
    Maybe (..),
    Num (..),
    Ord (..),
    Ordering (..),
    fromInteger,
  )
import qualified Prelude

-- $stream
--    The 'Stream' data type is an effectful series of steps with some
--    payload value at the bottom. The steps are represented with functors.
--    The effects are represented with some /control/ monad. (Control monads
--    must be bound to exactly once; see the documentation in
--    <https://github.com/tweag/linear-base/tree/master/src/Control/Monad/Linear.hs linear-base> to learn more
--    about control monads, control applicatives and control functors.)
--
--    In words, a @Stream f m r@ is either a payload of type @r@, or
--    a step of type @f (Stream f m r)@ or an effect of type @m (Stream f m r)@
--    where @f@ is a @Control.Functor@ and @m@ is a @Control.Monad@.
--
--    This module exports combinators that pertain to this general case.
--    Some of these are quite abstract and pervade any use of the library,
--    e.g.
--
-- >   maps    :: (forall x . f x %1-> g x) -> Stream f m r %1-> Stream g m r
-- >   mapped  :: (forall x. f x %1-> m (g x)) -> Stream f m r %1-> Stream g m r
-- >   concats :: Stream (Stream f m) m r %1-> Stream f m r
--
--    (assuming here and thoughout that @m@ or @n@ satisfies
--    a @Control.Monad@ constraint, and @f@ or @g@ a @Control.Functor@
--    constraint).
--
--    Others are surprisingly determinate in content:
--
-- >   chunksOf     :: Int -> Stream f m r %1-> Stream (Stream f m) m r
-- >   splitsAt     :: Int -> Stream f m r %1-> Stream f m (Stream f m r)
-- >   intercalates :: Stream f m () -> Stream (Stream f m) m r %1-> Stream f m r
-- >   unzips       :: Stream (Compose f g) m r %1->  Stream f (Stream g m) r
-- >   separate     :: Stream (Sum f g) m r -> Stream f (Stream g m) r  -- cp. partitionEithers
-- >   unseparate   :: Stream f (Stream g) m r -> Stream (Sum f g) m r
-- >   groups       :: Stream (Sum f g) m r %1-> Stream (Sum (Stream f m) (Stream g m)) m r
--
--    One way to see that /any/ streaming library needs some such general type is
--    that it is required to represent the segmentation of a stream, and to
--    express the equivalents of @Prelude/Data.List@ combinators that involve
--    'lists of lists' and the like. See for example this
--    <http://www.haskellforall.com/2013/09/perfect-streaming-using-pipes-bytestring.html post>
--    on the correct expression of a streaming \'lines\' function.
--    The module @Streaming.Prelude@ exports combinators relating to
-- > Stream (Of a) m r
--    where @Of a r = !a :> r@ is a left-strict pair.
--   This expresses the concept of a 'Producer' or 'Source' or 'Generator' and
--   easily inter-operates with types with such names in e.g. 'conduit',
--   'iostreams' and 'pipes'.

-- # Constructing a 'Stream' on a given functor
-------------------------------------------------------------------------------

-- Remark. By default we require `Control.Monad` and `Control.Functor`
-- instances for the `m` and `f` in a `Stream f m r` since these allow the
-- stream to have a `Control.Monad` instance

-- | @yields@ is like @lift@ for items in the streamed functor.
--    It makes a singleton or one-layer succession.
--
-- > lift :: (Control.Monad m, Control.Functor f)    => m r %1-> Stream f m r
-- > yields ::  (Control.Monad m, Control.Functor f) => f r %1-> Stream f m r
--
--    Viewed in another light, it is like a functor-general version of @yield@:
--
-- > S.yield a = yields (a :> ())
yields :: (Control.Monad m, Control.Functor f) => f r %1 -> Stream f m r
yields :: forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
f r %1 -> Stream f m r
yields f r
fr = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return f r
fr
{-# INLINE yields #-}

-- Note: This must consume its input linearly since it must bind to a
-- `Control.Monad`.

-- | Wrap an effect that returns a stream
--
-- > effect = join . lift
effect ::
  (Control.Monad m, Control.Functor f) =>
  m (Stream f m r) %1 ->
  Stream f m r
effect :: forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
m (Stream f m r) %1 -> Stream f m r
effect = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect
{-# INLINE effect #-}

-- | Wrap a new layer of a stream. So, e.g.
--
-- > S.cons :: Control.Monad m => a -> Stream (Of a) m r %1-> Stream (Of a) m r
-- > S.cons a str = wrap (a :> str)
--
--   and, recursively:
--
-- > S.each' :: Control.Monad m =>  [a] -> Stream (Of a) m ()
-- > S.each' = foldr (\a b -> wrap (a :> b)) (return ())
--
--   The two operations
--
-- > wrap :: (Control.Monad m, Control.Functor f) =>
-- >   f (Stream f m r) %1-> Stream f m r
-- > effect :: (Control.Monad m, Control.Functor f) =>
-- >   m (Stream f m r) %1-> Stream f m r
--
--   are fundamental. We can define the parallel operations @yields@ and @lift@
--   in terms of them
--
-- > yields :: (Control.Monad m, Control.Functor f) => f r %1-> Stream f m r
-- > yields = wrap . Control.fmap Control.return
-- > lift ::  (Control.Monad m, Control.Functor f)  => m r %1-> Stream f m r
-- > lift = effect . Control.fmap Control.return
wrap ::
  (Control.Monad m, Control.Functor f) =>
  f (Stream f m r) %1 ->
  Stream f m r
wrap :: forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
f (Stream f m r) %1 -> Stream f m r
wrap = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step
{-# INLINE wrap #-}

-- | Repeat a functorial layer, command or instruction a fixed number of times.
replicates ::
  (HasCallStack, Control.Monad m, Control.Functor f) =>
  Int ->
  f () ->
  Stream f m ()
replicates :: forall (m :: * -> *) (f :: * -> *).
(HasCallStack, Monad m, Functor f) =>
Int -> f () -> Stream f m ()
replicates Int
n f ()
f = forall (m :: * -> *) (f :: * -> *).
(HasCallStack, Monad m, Functor f) =>
Int -> f () -> Stream f m ()
replicates' Int
n f ()
f
  where
    replicates' ::
      (HasCallStack, Control.Monad m, Control.Functor f) =>
      Int ->
      f () ->
      Stream f m ()
    replicates' :: forall (m :: * -> *) (f :: * -> *).
(HasCallStack, Monad m, Functor f) =>
Int -> f () -> Stream f m ()
replicates' Int
n f ()
f = case forall a. Ord a => a -> a -> Ordering
compare Int
n Int
0 of
      Ordering
LT -> forall a. HasCallStack => [Char] -> a
Prelude.error [Char]
"replicates called with negative integer"
      Ordering
EQ -> forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return ()
      Ordering
GT -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (\() -> forall (m :: * -> *) (f :: * -> *).
(HasCallStack, Monad m, Functor f) =>
Int -> f () -> Stream f m ()
replicates (Int
n forall a. Num a => a -> a -> a
- Int
1) f ()
f) f ()
f
{-# INLINE replicates #-}

-- | @replicatesM n@ repeats an effect containing a functorial layer, command
-- or instruction @n@ times.
replicatesM ::
  forall f m.
  (Control.Monad m, Control.Functor f) =>
  Int ->
  m (f ()) ->
  Stream f m ()
replicatesM :: forall (f :: * -> *) (m :: * -> *).
(Monad m, Functor f) =>
Int -> m (f ()) -> Stream f m ()
replicatesM = Int -> m (f ()) -> Stream f m ()
loop
  where
    loop :: Int -> m (f ()) -> Stream f m ()
    loop :: Int -> m (f ()) -> Stream f m ()
loop Int
n m (f ())
mfstep
      | Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return ()
      | Bool
Prelude.otherwise =
          forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$
            forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (\() -> Int -> m (f ()) -> Stream f m ()
loop (Int
n forall a. Num a => a -> a -> a
- Int
1) m (f ())
mfstep)) m (f ())
mfstep
{-# INLINEABLE replicatesM #-}

unfold ::
  (Control.Monad m, Control.Functor f) =>
  (s %1 -> m (Either r (f s))) ->
  s %1 ->
  Stream f m r
unfold :: forall (m :: * -> *) (f :: * -> *) s r.
(Monad m, Functor f) =>
(s %1 -> m (Either r (f s))) -> s %1 -> Stream f m r
unfold s %1 -> m (Either r (f s))
step s
state = forall (m :: * -> *) (f :: * -> *) s r.
(Monad m, Functor f) =>
(s %1 -> m (Either r (f s))) -> s %1 -> Stream f m r
unfold' s %1 -> m (Either r (f s))
step s
state
  where
    unfold' ::
      (Control.Monad m, Control.Functor f) =>
      (s %1 -> m (Either r (f s))) ->
      s %1 ->
      Stream f m r
    unfold' :: forall (m :: * -> *) (f :: * -> *) s r.
(Monad m, Functor f) =>
(s %1 -> m (Either r (f s))) -> s %1 -> Stream f m r
unfold' s %1 -> m (Either r (f s))
step s
state = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Control.do
      Either r (f s)
either <- s %1 -> m (Either r (f s))
step s
state
      Either r (f s)
either forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Left r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
        Right (f s
fs) -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (forall (m :: * -> *) (f :: * -> *) s r.
(Monad m, Functor f) =>
(s %1 -> m (Either r (f s))) -> s %1 -> Stream f m r
unfold s %1 -> m (Either r (f s))
step) f s
fs
{-# INLINEABLE unfold #-}

-- Note. To keep restrictions minimal, we use the `Data.Applicative`
-- instance.
untilJust ::
  forall f m r.
  (Control.Monad m, Data.Applicative f) =>
  m (Maybe r) ->
  Stream f m r
untilJust :: forall (f :: * -> *) (m :: * -> *) r.
(Monad m, Applicative f) =>
m (Maybe r) -> Stream f m r
untilJust m (Maybe r)
action = Stream f m r
loop
  where
    loop :: Stream f m r
    loop :: Stream f m r
loop = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Control.do
      Maybe r
maybeVal <- m (Maybe r)
action
      Maybe r
maybeVal forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Maybe r
Nothing -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
Data.pure Stream f m r
loop
        Just r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
{-# INLINEABLE untilJust #-}

-- Remark. The linear church encoding of streams has linear
-- return, effect and step functions.

-- | Reflect a church-encoded stream; cp. @GHC.Exts.build@
--
-- > streamFold return_ effect_ step_ (streamBuild psi) = psi return_ effect_ step_
streamBuild ::
  (forall b. (r %1 -> b) -> (m b %1 -> b) -> (f b %1 -> b) -> b) -> Stream f m r
streamBuild :: forall r (m :: * -> *) (f :: * -> *).
(forall b. (r %1 -> b) -> (m b %1 -> b) -> (f b %1 -> b) -> b)
-> Stream f m r
streamBuild = \forall b. (r %1 -> b) -> (m b %1 -> b) -> (f b %1 -> b) -> b
phi -> forall b. (r %1 -> b) -> (m b %1 -> b) -> (f b %1 -> b) -> b
phi forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step
{-# INLINE streamBuild #-}

-- Note. To keep requirements minimal, we use the `Data.Applicative`
-- instance instead of the `Control.Applicative` instance.
delays :: forall f r. (Data.Applicative f) => Double -> Stream f IO r
delays :: forall (f :: * -> *) r. Applicative f => Double -> Stream f IO r
delays Double
seconds = Stream f IO r
loop
  where
    loop :: Stream f IO r
    loop :: Stream f IO r
loop = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Control.do
      let delay :: Int
delay = forall a. Num a => Integer -> a
fromInteger (forall a b. (RealFrac a, Integral b) => a -> b
Prelude.truncate (Double
1000000 forall a. Num a => a -> a -> a
* Double
seconds))
      () <- forall a. IO a %1 -> IO a
fromSystemIO forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Int -> IO ()
threadDelay Int
delay
      forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
Data.pure Stream f IO r
loop
{-# INLINEABLE delays #-}

-- # Transforming streams
-------------------------------------------------------------------------------

-- | Map layers of one functor to another with a transformation.
--
-- > maps id = id
-- > maps f . maps g = maps (f . g)
maps ::
  forall f g m r.
  (Control.Monad m, Control.Functor f) =>
  (forall x. f x %1 -> g x) ->
  Stream f m r %1 ->
  Stream g m r
maps :: forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
(forall x. f x %1 -> g x) -> Stream f m r %1 -> Stream g m r
maps = forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
(forall x. f x %1 -> g x) -> Stream f m r %1 -> Stream g m r
Stream.maps
{-# INLINE maps #-}

-- | Map layers of one functor to another with a transformation.
--
-- > mapsPost id = id
-- > mapsPost f . mapsPost g = mapsPost (f . g)
-- > mapsPost f = maps f
--
--     @mapsPost@ is essentially the same as 'maps', but it imposes a @Control.Functor@ constraint on
--     its target functor rather than its source functor. It should be preferred if @Control.fmap@
--     is cheaper for the target functor than for the source functor.
mapsPost ::
  forall m f g r.
  (Control.Monad m, Control.Functor g) =>
  (forall x. f x %1 -> g x) ->
  Stream f m r %1 ->
  Stream g m r
mapsPost :: forall (m :: * -> *) (f :: * -> *) (g :: * -> *) r.
(Monad m, Functor g) =>
(forall x. f x %1 -> g x) -> Stream f m r %1 -> Stream g m r
mapsPost = forall (m :: * -> *) (f :: * -> *) (g :: * -> *) r.
(Monad m, Functor g) =>
(forall x. f x %1 -> g x) -> Stream f m r %1 -> Stream g m r
Stream.mapsPost
{-# INLINE mapsPost #-}

-- Note. The transformation function must be linear so that the stream
-- held inside a control functor is used linearly.

-- | Map layers of one functor to another with a transformation involving the base monad.
--     'maps' is more fundamental than @mapsM@, which is best understood as a convenience
--     for effecting this frequent composition:
--
-- > mapsM phi = decompose . maps (Compose . phi)
--
--     The streaming prelude exports the same function under the better name @mapped@,
--     which overlaps with the lens libraries.
mapsM ::
  forall f g m r.
  (Control.Monad m, Control.Functor f) =>
  (forall x. f x %1 -> m (g x)) ->
  Stream f m r %1 ->
  Stream g m r
mapsM :: forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
(forall x. f x %1 -> m (g x)) -> Stream f m r %1 -> Stream g m r
mapsM forall x. f x %1 -> m (g x)
transform = Stream f m r %1 -> Stream g m r
loop
  where
    loop :: Stream f m r %1 -> Stream g m r
    loop :: Stream f m r %1 -> Stream g m r
loop Stream f m r
stream =
      Stream f m r
stream forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Return r
r -> forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
        Step f (Stream f m r)
f -> forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall x. f x %1 -> m (g x)
transform forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream f m r %1 -> Stream g m r
loop f (Stream f m r)
f
        Effect m (Stream f m r)
m -> forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream f m r %1 -> Stream g m r
loop m (Stream f m r)
m
{-# INLINE mapsM #-}

-- | Map layers of one functor to another with a transformation involving the base monad.
--     @mapsMPost@ is essentially the same as 'mapsM', but it imposes a @Control.Functor@ constraint on
--     its target functor rather than its source functor. It should be preferred if @Control.fmap@
--     is cheaper for the target functor than for the source functor.
--
--     @mapsPost@ is more fundamental than @mapsMPost@, which is best understood as a convenience
--     for effecting this frequent composition:
--
-- > mapsMPost phi = decompose . mapsPost (Compose . phi)
--
--     The streaming prelude exports the same function under the better name @mappedPost@,
--     which overlaps with the lens libraries.
mapsMPost ::
  forall m f g r.
  (Control.Monad m, Control.Functor g) =>
  (forall x. f x %1 -> m (g x)) ->
  Stream f m r %1 ->
  Stream g m r
mapsMPost :: forall (m :: * -> *) (f :: * -> *) (g :: * -> *) r.
(Monad m, Functor g) =>
(forall x. f x %1 -> m (g x)) -> Stream f m r %1 -> Stream g m r
mapsMPost = forall (m :: * -> *) (f :: * -> *) (g :: * -> *) r.
(Monad m, Functor g) =>
(forall x. f x %1 -> m (g x)) -> Stream f m r %1 -> Stream g m r
Stream.mapsMPost
{-# INLINE mapsMPost #-}

-- | Map layers of one functor to another with a transformation involving the base monad.
--     This could be trivial, e.g.
--
-- > let noteBeginning text x = (fromSystemIO (System.putStrLn text)) Control.>> (Control.return x)
--
--     this is completely functor-general
--
--     @maps@ and @mapped@ obey these rules:
--
-- > maps id              = id
-- > mapped return        = id
-- > maps f . maps g      = maps (f . g)
-- > mapped f . mapped g  = mapped (f <=< g)
-- > maps f . mapped g    = mapped (fmap f . g)
-- > mapped f . maps g    = mapped (f <=< fmap g)
--
--     @maps@ is more fundamental than @mapped@, which is best understood as a convenience
--     for effecting this frequent composition:
--
-- > mapped phi = decompose . maps (Compose . phi)
mapped ::
  forall f g m r.
  (Control.Monad m, Control.Functor f) =>
  (forall x. f x %1 -> m (g x)) ->
  Stream f m r %1 ->
  Stream g m r
mapped :: forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
(forall x. f x %1 -> m (g x)) -> Stream f m r %1 -> Stream g m r
mapped = forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
(forall x. f x %1 -> m (g x)) -> Stream f m r %1 -> Stream g m r
mapsM
{-# INLINE mapped #-}

-- | A version of 'mapped' that imposes a @Control.Functor@ constraint on the target functor rather
--    than the source functor. This version should be preferred if @Control.fmap@ on the target
--    functor is cheaper.
mappedPost ::
  forall m f g r.
  (Control.Monad m, Control.Functor g) =>
  (forall x. f x %1 -> m (g x)) ->
  Stream f m r %1 ->
  Stream g m r
mappedPost :: forall (m :: * -> *) (f :: * -> *) (g :: * -> *) r.
(Monad m, Functor g) =>
(forall x. f x %1 -> m (g x)) -> Stream f m r %1 -> Stream g m r
mappedPost = forall (m :: * -> *) (f :: * -> *) (g :: * -> *) r.
(Monad m, Functor g) =>
(forall x. f x %1 -> m (g x)) -> Stream f m r %1 -> Stream g m r
mapsMPost
{-# INLINE mappedPost #-}

-- | A less-efficient version of 'hoist' that works properly even when its
-- argument is not a monad morphism.
hoistUnexposed ::
  forall f m n r.
  (Control.Monad m, Control.Functor f) =>
  (forall a. m a %1 -> n a) ->
  Stream f m r %1 ->
  Stream f n r
hoistUnexposed :: forall (f :: * -> *) (m :: * -> *) (n :: * -> *) r.
(Monad m, Functor f) =>
(forall a. m a %1 -> n a) -> Stream f m r %1 -> Stream f n r
hoistUnexposed forall a. m a %1 -> n a
trans = Stream f m r %1 -> Stream f n r
loop
  where
    loop :: Stream f m r %1 -> Stream f n r
    loop :: Stream f m r %1 -> Stream f n r
loop =
      forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect
        forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall a. m a %1 -> n a
trans
        forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) (m :: * -> *) r a.
Monad m =>
(r %1 -> m a)
-> (f (Stream f m r) %1 -> m a) -> Stream f m r %1 -> m a
inspectC
          (forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return)
          (forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream f m r %1 -> Stream f n r
loop)
{-# INLINEABLE hoistUnexposed #-}

-- A version of 'inspect' that takes explicit continuations.
-- Note that due to the linear constructors of 'Stream', these continuations
-- are linear.
inspectC ::
  forall f m r a.
  (Control.Monad m) =>
  (r %1 -> m a) ->
  (f (Stream f m r) %1 -> m a) ->
  Stream f m r %1 ->
  m a
inspectC :: forall (f :: * -> *) (m :: * -> *) r a.
Monad m =>
(r %1 -> m a)
-> (f (Stream f m r) %1 -> m a) -> Stream f m r %1 -> m a
inspectC r %1 -> m a
f f (Stream f m r) %1 -> m a
g = Stream f m r %1 -> m a
loop
  where
    loop :: Stream f m r %1 -> m a
    loop :: Stream f m r %1 -> m a
loop (Return r
r) = r %1 -> m a
f r
r
    loop (Step f (Stream f m r)
x) = f (Stream f m r) %1 -> m a
g f (Stream f m r)
x
    loop (Effect m (Stream f m r)
m) = m (Stream f m r)
m forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= Stream f m r %1 -> m a
loop
{-# INLINE inspectC #-}

-- | Group layers in an alternating stream into adjoining sub-streams
--    of one type or another.
groups ::
  forall f g m r.
  (Control.Monad m, Control.Functor f, Control.Functor g) =>
  Stream (Sum f g) m r %1 ->
  Stream (Sum (Stream f m) (Stream g m)) m r
groups :: forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f, Functor g) =>
Stream (Sum f g) m r
%1 -> Stream (Sum (Stream f m) (Stream g m)) m r
groups = Stream (Sum f g) m r
%1 -> Stream (Sum (Stream f m) (Stream g m)) m r
loop
  where
    loop :: Stream (Sum f g) m r %1 -> Stream (Sum (Stream f m) (Stream g m)) m r
    loop :: Stream (Sum f g) m r
%1 -> Stream (Sum (Stream f m) (Stream g m)) m r
loop Stream (Sum f g) m r
str = Control.do
      Either r (Sum f g (Stream (Sum f g) m r))
e <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Control.lift forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
Monad m =>
Stream f m r %1 -> m (Either r (f (Stream f m r)))
inspect Stream (Sum f g) m r
str
      Either r (Sum f g (Stream (Sum f g) m r))
e forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Left r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return r
r
        Right Sum f g (Stream (Sum f g) m r)
ostr ->
          Sum f g (Stream (Sum f g) m r)
ostr forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
            InR g (Stream (Sum f g) m r)
gstr -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream (Sum f g) m r
%1 -> Stream (Sum (Stream f m) (Stream g m)) m r
loop forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Stream (Sum f g) m r %1 -> Stream g m (Stream (Sum f g) m r)
cleanR (forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR g (Stream (Sum f g) m r)
gstr))
            InL f (Stream (Sum f g) m r)
fstr -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream (Sum f g) m r
%1 -> Stream (Sum (Stream f m) (Stream g m)) m r
loop forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Stream (Sum f g) m r %1 -> Stream f m (Stream (Sum f g) m r)
cleanL (forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL f (Stream (Sum f g) m r)
fstr))

    cleanL :: Stream (Sum f g) m r %1 -> Stream f m (Stream (Sum f g) m r)
    cleanL :: Stream (Sum f g) m r %1 -> Stream f m (Stream (Sum f g) m r)
cleanL = Stream (Sum f g) m r %1 -> Stream f m (Stream (Sum f g) m r)
go
      where
        go :: Stream (Sum f g) m r %1 -> Stream f m (Stream (Sum f g) m r)
        go :: Stream (Sum f g) m r %1 -> Stream f m (Stream (Sum f g) m r)
go Stream (Sum f g) m r
s = Control.do
          Either r (Sum f g (Stream (Sum f g) m r))
e <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Control.lift forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
Monad m =>
Stream f m r %1 -> m (Either r (f (Stream f m r)))
inspect Stream (Sum f g) m r
s
          Either r (Sum f g (Stream (Sum f g) m r))
e forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
            Left r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return r
r
            Right (InL f (Stream (Sum f g) m r)
fstr) -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream (Sum f g) m r %1 -> Stream f m (Stream (Sum f g) m r)
go f (Stream (Sum f g) m r)
fstr
            Right (InR g (Stream (Sum f g) m r)
gstr) -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR g (Stream (Sum f g) m r)
gstr)

    cleanR :: Stream (Sum f g) m r %1 -> Stream g m (Stream (Sum f g) m r)
    cleanR :: Stream (Sum f g) m r %1 -> Stream g m (Stream (Sum f g) m r)
cleanR = Stream (Sum f g) m r %1 -> Stream g m (Stream (Sum f g) m r)
go
      where
        go :: Stream (Sum f g) m r %1 -> Stream g m (Stream (Sum f g) m r)
        go :: Stream (Sum f g) m r %1 -> Stream g m (Stream (Sum f g) m r)
go Stream (Sum f g) m r
s = Control.do
          Either r (Sum f g (Stream (Sum f g) m r))
e <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Control.lift forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
Monad m =>
Stream f m r %1 -> m (Either r (f (Stream f m r)))
inspect Stream (Sum f g) m r
s
          Either r (Sum f g (Stream (Sum f g) m r))
e forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
            Left r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return r
r
            Right (InL f (Stream (Sum f g) m r)
fstr) -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL f (Stream (Sum f g) m r)
fstr)
            Right (InR g (Stream (Sum f g) m r)
gstr) -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream (Sum f g) m r %1 -> Stream g m (Stream (Sum f g) m r)
go g (Stream (Sum f g) m r)
gstr
{-# INLINEABLE groups #-}

-- # Inspecting a Stream
-------------------------------------------------------------------------------

-- | Inspect the first stage of a freely layered sequence.
--    Compare @Pipes.next@ and the replica @Streaming.Prelude.next@.
--    This is the 'uncons' for the general 'unfold'.
--
-- > unfold inspect = id
-- > Streaming.Prelude.unfoldr StreamingPrelude.next = id
inspect ::
  forall f m r.
  (Control.Monad m) =>
  Stream f m r %1 ->
  m (Either r (f (Stream f m r)))
inspect :: forall (f :: * -> *) (m :: * -> *) r.
Monad m =>
Stream f m r %1 -> m (Either r (f (Stream f m r)))
inspect = Stream f m r %1 -> m (Either r (f (Stream f m r)))
loop
  where
    loop :: Stream f m r %1 -> m (Either r (f (Stream f m r)))
    loop :: Stream f m r %1 -> m (Either r (f (Stream f m r)))
loop Stream f m r
stream =
      Stream f m r
stream forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Return r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return (forall a b. a -> Either a b
Left r
r)
        Effect m (Stream f m r)
m -> m (Stream f m r)
m forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= Stream f m r %1 -> m (Either r (f (Stream f m r)))
loop
        Step f (Stream f m r)
fs -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return (forall a b. b -> Either a b
Right f (Stream f m r)
fs)
{-# INLINEABLE inspect #-}

-- # Splitting and joining 'Stream's
-------------------------------------------------------------------------------

-- | Split a succession of layers after some number, returning a streaming or
--    effectful pair.
--
-- \>\>\> rest <- S.print $ S.splitAt 1 $ each' [1..3]
-- 1
-- \>\>\> S.print rest
-- 2
-- 3
--
-- > splitAt 0 = return
-- > (\stream -> splitAt n stream >>= splitAt m) = splitAt (m+n)
--
--    Thus, e.g.
--
-- \>\>\> rest <- S.print $ (\s -> splitsAt 2 s >>= splitsAt 2) each' [1..5]
-- 1
-- 2
-- 3
-- 4
-- \>\>\> S.print rest
-- 5
splitsAt ::
  forall f m r.
  (HasCallStack, Control.Monad m, Control.Functor f) =>
  Int ->
  Stream f m r %1 ->
  Stream f m (Stream f m r)
splitsAt :: forall (f :: * -> *) (m :: * -> *) r.
(HasCallStack, Monad m, Functor f) =>
Int -> Stream f m r %1 -> Stream f m (Stream f m r)
splitsAt Int
n Stream f m r
stream = Int -> Stream f m r %1 -> Stream f m (Stream f m r)
loop Int
n Stream f m r
stream
  where
    loop :: Int -> Stream f m r %1 -> Stream f m (Stream f m r)
    loop :: Int -> Stream f m r %1 -> Stream f m (Stream f m r)
loop Int
n Stream f m r
stream = case forall a. Ord a => a -> a -> Ordering
compare Int
n Int
0 of
      Ordering
LT -> forall a. HasCallStack => [Char] -> a
Prelude.error [Char]
"splitsAt called with negative index" forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Stream f m r
stream
      Ordering
EQ -> forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return Stream f m r
stream
      Ordering
GT ->
        Stream f m r
stream forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
          Return r
r -> forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
          Effect m (Stream f m r)
m -> forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (Int -> Stream f m r %1 -> Stream f m (Stream f m r)
loop Int
n) m (Stream f m r)
m
          Step f (Stream f m r)
f -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (Int -> Stream f m r %1 -> Stream f m (Stream f m r)
loop (Int
n forall a. Num a => a -> a -> a
- Int
1)) f (Stream f m r)
f
{-# INLINEABLE splitsAt #-}

-- | Break a stream into substreams each with n functorial layers.
--
-- \>\>\>  S.print $ mapped S.sum $ chunksOf 2 $ each' [1,1,1,1,1]
-- 2
-- 2
-- 1
chunksOf ::
  forall f m r.
  (HasCallStack, Control.Monad m, Control.Functor f) =>
  Int ->
  Stream f m r %1 ->
  Stream (Stream f m) m r
chunksOf :: forall (f :: * -> *) (m :: * -> *) r.
(HasCallStack, Monad m, Functor f) =>
Int -> Stream f m r %1 -> Stream (Stream f m) m r
chunksOf Int
n Stream f m r
stream = Int -> Stream f m r %1 -> Stream (Stream f m) m r
loop Int
n Stream f m r
stream
  where
    loop :: Int -> Stream f m r %1 -> Stream (Stream f m) m r
    loop :: Int -> Stream f m r %1 -> Stream (Stream f m) m r
loop Int
_ (Return r
r) = forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
    loop Int
n Stream f m r
stream = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (Int -> Stream f m r %1 -> Stream (Stream f m) m r
loop Int
n) forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
(HasCallStack, Monad m, Functor f) =>
Int -> Stream f m r %1 -> Stream f m (Stream f m r)
splitsAt Int
n Stream f m r
stream
{-# INLINEABLE chunksOf #-}

-- | Dissolves the segmentation into layers of @Stream f m@ layers.
concats ::
  forall f m r.
  (Control.Monad m, Control.Functor f) =>
  Stream (Stream f m) m r %1 ->
  Stream f m r
concats :: forall (f :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
Stream (Stream f m) m r %1 -> Stream f m r
concats = Stream (Stream f m) m r %1 -> Stream f m r
loop
  where
    loop :: Stream (Stream f m) m r %1 -> Stream f m r
    loop :: Stream (Stream f m) m r %1 -> Stream f m r
loop Stream (Stream f m) m r
stream =
      Stream (Stream f m) m r
stream forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Return r
r -> forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
        Effect m (Stream (Stream f m) m r)
m -> forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream (Stream f m) m r %1 -> Stream f m r
loop m (Stream (Stream f m) m r)
m
        Step Stream f m (Stream (Stream f m) m r)
f -> Control.do
          Stream f m r
rest <- forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream (Stream f m) m r %1 -> Stream f m r
loop Stream f m (Stream (Stream f m) m r)
f
          Stream f m r
rest
{-# INLINE concats #-}

-- Note. To keep the monad of the stream a control monad, we need
-- `(t m)` to be a control monad, and hence `t` to be a control
-- monad transformer.

-- | Interpolate a layer at each segment. This specializes to e.g.
--
-- > intercalates :: Stream f m () -> Stream (Stream f m) m r %1-> Stream f m r
intercalates ::
  forall t m r x.
  (Control.Monad m, Control.Monad (t m), Control.MonadTrans t, Consumable x) =>
  t m x ->
  Stream (t m) m r %1 ->
  t m r
intercalates :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) r x.
(Monad m, Monad (t m), MonadTrans t, Consumable x) =>
t m x -> Stream (t m) m r %1 -> t m r
intercalates t m x
sep = Stream (t m) m r %1 -> t m r
go0
  where
    go0 :: Stream (t m) m r %1 -> t m r
    go0 :: Stream (t m) m r %1 -> t m r
go0 Stream (t m) m r
f =
      Stream (t m) m r
f forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Return r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return r
r
        Effect m (Stream (t m) m r)
m -> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Control.lift m (Stream (t m) m r)
m forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= Stream (t m) m r %1 -> t m r
go0
        Step t m (Stream (t m) m r)
fstr -> Control.do
          Stream (t m) m r
f' <- t m (Stream (t m) m r)
fstr
          Stream (t m) m r %1 -> t m r
go1 Stream (t m) m r
f'

    go1 :: Stream (t m) m r %1 -> t m r
    go1 :: Stream (t m) m r %1 -> t m r
go1 Stream (t m) m r
f =
      Stream (t m) m r
f forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Return r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return r
r
        Effect m (Stream (t m) m r)
m -> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Control.lift m (Stream (t m) m r)
m forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= Stream (t m) m r %1 -> t m r
go1
        Step t m (Stream (t m) m r)
fstr -> Control.do
          x
x <- t m x
sep
          forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall a. Consumable a => a %1 -> ()
consume x
x
          Stream (t m) m r
f' <- t m (Stream (t m) m r)
fstr
          Stream (t m) m r %1 -> t m r
go1 Stream (t m) m r
f'
{-# INLINEABLE intercalates #-}

-- # Zipping, unzipping, separating and unseparating streams
-------------------------------------------------------------------------------

unzips ::
  forall f g m r.
  (Control.Monad m, Control.Functor f, Control.Functor g) =>
  Stream (Compose f g) m r %1 ->
  Stream f (Stream g m) r
unzips :: forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f, Functor g) =>
Stream (Compose f g) m r %1 -> Stream f (Stream g m) r
unzips Stream (Compose f g) m r
str =
  forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r
%1 -> (f b %1 -> b) -> (m b %1 -> b) -> (r %1 -> b) -> b
destroyExposed
    Stream (Compose f g) m r
str
    (\(Compose f (g (Stream f (Stream g m) r))
fgstr) -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
f r %1 -> Stream f m r
yields) f (g (Stream f (Stream g m) r))
fgstr))
    (forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Control.lift)
    forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return
{-# INLINEABLE unzips #-}

-- | Given a stream on a sum of functors, make it a stream on the left functor,
--    with the streaming on the other functor as the governing monad. This is
--    useful for acting on one or the other functor with a fold, leaving the
--    other material for another treatment. It generalizes
--    'Data.Either.partitionEithers', but actually streams properly.
--
-- \>\>\> let odd_even = S.maps (S.distinguish even) $ S.each' [1..10::Int]
-- \>\>\> :t separate odd_even
-- separate odd_even
--  :: Monad m => Stream (Of Int) (Stream (Of Int) m) ()
--
--    Now, for example, it is convenient to fold on the left and right values separately:
--
-- \>\>\> S.toList $ S.toList $ separate odd_even
-- [2,4,6,8,10] :> ([1,3,5,7,9] :> ())
--
--
--   Or we can write them to separate files or whatever:
--
-- \>\>\> S.writeFile "even.txt" . S.show $ S.writeFile "odd.txt" . S.show $ S.separate odd_even
-- \>\>\> :! cat even.txt
-- 2
-- 4
-- 6
-- 8
-- 10
-- \>\>\> :! cat odd.txt
-- 1
-- 3
-- 5
-- 7
-- 9
--
--   Of course, in the special case of @Stream (Of a) m r@, we can achieve the above
--   effects more simply by using 'Streaming.Prelude.copy'
--
-- \>\>\> S.toList . S.filter even $ S.toList . S.filter odd $ S.copy $ each [1..10::Int]
-- [2,4,6,8,10] :> ([1,3,5,7,9] :> ())
--
--
--    But 'separate' and 'unseparate' are functor-general.
separate ::
  forall f g m r.
  (Control.Monad m, Control.Functor f, Control.Functor g) =>
  Stream (Sum f g) m r ->
  Stream f (Stream g m) r
separate :: forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f, Functor g) =>
Stream (Sum f g) m r -> Stream f (Stream g m) r
separate Stream (Sum f g) m r
str = forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r
%1 -> (f b %1 -> b) -> (m b %1 -> b) -> (r %1 -> b) -> b
destroyExposed Stream (Sum f g) m r
str Sum f g (Stream f (Stream g m) r) %1 -> Stream f (Stream g m) r
construct (forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Control.lift) forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return
  where
    construct :: Sum f g (Stream f (Stream g m) r) %1 -> Stream f (Stream g m) r
    construct :: Sum f g (Stream f (Stream g m) r) %1 -> Stream f (Stream g m) r
construct (InL f (Stream f (Stream g m) r)
fss) = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step f (Stream f (Stream g m) r)
fss
    construct (InR g (Stream f (Stream g m) r)
gss) = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
f r %1 -> Stream f m r
yields g (Stream f (Stream g m) r)
gss)
{-# INLINEABLE separate #-}

unseparate ::
  (Control.Monad m, Control.Functor f, Control.Functor g) =>
  Stream f (Stream g m) r ->
  Stream (Sum f g) m r
unseparate :: forall (m :: * -> *) (f :: * -> *) (g :: * -> *) r.
(Monad m, Functor f, Functor g) =>
Stream f (Stream g m) r -> Stream (Sum f g) m r
unseparate Stream f (Stream g m) r
str =
  forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r
%1 -> (f b %1 -> b) -> (m b %1 -> b) -> (r %1 -> b) -> b
destroyExposed
    Stream f (Stream g m) r
str
    (forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL)
    (forall (m :: * -> *) a. Monad m => m (m a) %1 -> m a
Control.join forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
(forall x. f x %1 -> g x) -> Stream f m r %1 -> Stream g m r
maps forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR)
    forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return
{-# INLINEABLE unseparate #-}

-- | Rearrange a succession of layers of the form @Compose m (f x)@.
--
--   we could as well define @decompose@ by @mapsM@:
--
-- > decompose = mapped getCompose
--
--  but @mapped@ is best understood as:
--
-- > mapped phi = decompose . maps (Compose . phi)
--
--  since @maps@ and @hoist@ are the really fundamental operations that preserve the
--  shape of the stream:
--
-- > maps  :: (Control.Monad m, Control.Functor f) => (forall x. f x %1-> g x) -> Stream f m r %1-> Stream g m r
-- > hoist :: (Control.Monad m, Control.Functor f) => (forall a. m a %1-> n a) -> Stream f m r %1-> Stream f n r
decompose ::
  forall f m r.
  (Control.Monad m, Control.Functor f) =>
  Stream (Compose m f) m r %1 ->
  Stream f m r
decompose :: forall (f :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
Stream (Compose m f) m r %1 -> Stream f m r
decompose = Stream (Compose m f) m r %1 -> Stream f m r
loop
  where
    loop :: Stream (Compose m f) m r %1 -> Stream f m r
    loop :: Stream (Compose m f) m r %1 -> Stream f m r
loop Stream (Compose m f) m r
stream =
      Stream (Compose m f) m r
stream forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Return r
r -> forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
        Effect m (Stream (Compose m f) m r)
m -> forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream (Compose m f) m r %1 -> Stream f m r
loop m (Stream (Compose m f) m r)
m
        Step (Compose m (f (Stream (Compose m f) m r))
mfs) -> forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Control.do
          f (Stream (Compose m f) m r)
fstream <- m (f (Stream (Compose m f) m r))
mfs
          forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream (Compose m f) m r %1 -> Stream f m r
loop f (Stream (Compose m f) m r)
fstream)
{-# INLINEABLE decompose #-}

-- Note. For 'loop' to recurse over functoral steps, it must be a
-- linear function, and hence, `ext` must be linear in its second argument.
-- Further, the first argument of `ext` ought to be a linear function,
-- because it is typically applied to the input stream in `ext`, and hence
-- should be linear.

-- | If 'Of' had a @Comonad@ instance, then we'd have
--
-- @copy = expand extend@
--
-- See 'expandPost' for a version that requires a @Control.Functor g@
-- instance instead.
expand ::
  forall f m r g h.
  (Control.Monad m, Control.Functor f) =>
  (forall a b. (g a %1 -> b) -> f a %1 -> h b) ->
  Stream f m r %1 ->
  Stream g (Stream h m) r
expand :: forall (f :: * -> *) (m :: * -> *) r (g :: * -> *) (h :: * -> *).
(Monad m, Functor f) =>
(forall a b. (g a %1 -> b) -> f a %1 -> h b)
-> Stream f m r %1 -> Stream g (Stream h m) r
expand forall a b. (g a %1 -> b) -> f a %1 -> h b
ext = Stream f m r %1 -> Stream g (Stream h m) r
loop
  where
    loop :: Stream f m r %1 -> Stream g (Stream h m) r
    loop :: Stream f m r %1 -> Stream g (Stream h m) r
loop (Return r
r) = forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
    loop (Step f (Stream f m r)
f) = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall a b. (g a %1 -> b) -> f a %1 -> h b
ext (forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step) (forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream f m r %1 -> Stream g (Stream h m) r
loop f (Stream f m r)
f)
    loop (Effect m (Stream f m r)
m) = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Stream f m r %1 -> Stream g (Stream h m) r
loop) m (Stream f m r)
m
{-# INLINEABLE expand #-}

-- See note on 'expand'.

-- | If 'Of' had a @Comonad@ instance, then we'd have
--
-- @copy = expandPost extend@
--
-- See 'expand' for a version that requires a @Control.Functor f@ instance
-- instead.
expandPost ::
  forall f m r g h.
  (Control.Monad m, Control.Functor g) =>
  (forall a b. (g a %1 -> b) -> f a %1 -> h b) ->
  Stream f m r %1 ->
  Stream g (Stream h m) r
expandPost :: forall (f :: * -> *) (m :: * -> *) r (g :: * -> *) (h :: * -> *).
(Monad m, Functor g) =>
(forall a b. (g a %1 -> b) -> f a %1 -> h b)
-> Stream f m r %1 -> Stream g (Stream h m) r
expandPost forall a b. (g a %1 -> b) -> f a %1 -> h b
ext = Stream f m r %1 -> Stream g (Stream h m) r
loop
  where
    loop :: Stream f m r %1 -> Stream g (Stream h m) r
    loop :: Stream f m r %1 -> Stream g (Stream h m) r
loop (Return r
r) = forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return r
r
    loop (Step f (Stream f m r)
f) = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall a b. (g a %1 -> b) -> f a %1 -> h b
ext (forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap Stream f m r %1 -> Stream g (Stream h m) r
loop) f (Stream f m r)
f
    loop (Effect m (Stream f m r)
m) = forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Stream f m r %1 -> Stream g (Stream h m) r
loop) m (Stream f m r)
m
{-# INLINEABLE expandPost #-}

-- # Eliminating a 'Stream'
-------------------------------------------------------------------------------

-- Note. Since the functor step is held linearly in the
-- 'Stream' datatype, the first argument must be a linear function
-- in order to linearly consume the 'Step' case of a stream.

-- | Map each layer to an effect, and run them all.
mapsM_ ::
  (Control.Functor f, Control.Monad m) =>
  (forall x. f x %1 -> m x) ->
  Stream f m r %1 ->
  m r
mapsM_ :: forall (f :: * -> *) (m :: * -> *) r.
(Functor f, Monad m) =>
(forall x. f x %1 -> m x) -> Stream f m r %1 -> m r
mapsM_ forall x. f x %1 -> m x
f = forall (m :: * -> *) r. Monad m => Stream m m r %1 -> m r
run forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (f :: * -> *) (g :: * -> *) (m :: * -> *) r.
(Monad m, Functor f) =>
(forall x. f x %1 -> g x) -> Stream f m r %1 -> Stream g m r
maps forall x. f x %1 -> m x
f
{-# INLINE mapsM_ #-}

-- | Run the effects in a stream that merely layers effects.
run :: (Control.Monad m) => Stream m m r %1 -> m r
run :: forall (m :: * -> *) r. Monad m => Stream m m r %1 -> m r
run = forall (m :: * -> *) r. Monad m => Stream m m r %1 -> m r
loop
  where
    loop :: (Control.Monad m) => Stream m m r %1 -> m r
    loop :: forall (m :: * -> *) r. Monad m => Stream m m r %1 -> m r
loop Stream m m r
stream =
      Stream m m r
stream forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Return r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return r
r
        Effect m (Stream m m r)
m -> m (Stream m m r)
m forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= forall (m :: * -> *) r. Monad m => Stream m m r %1 -> m r
loop
        Step m (Stream m m r)
mrest -> m (Stream m m r)
mrest forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= forall (m :: * -> *) r. Monad m => Stream m m r %1 -> m r
loop
{-# INLINEABLE run #-}

-- | 'streamFold' reorders the arguments of 'destroy' to be more akin
--    to @foldr@  It is more convenient to query in ghci to figure out
--    what kind of \'algebra\' you need to write.
--
-- \>\>\> :t streamFold Control.return Control.join
-- (Control.Monad m, Control.Functor f) =>
--     (f (m a) %1-> m a) -> Stream f m a %1-> m a        -- iterT
--
-- \>\>\> :t streamFold Control.return (Control.join . Control.lift)
-- (Control.Monad m, Control.Monad (t m), Control.Functor f, Control.MonadTrans t) =>
--     (f (t m a) %1-> t m a) -> Stream f m a %1-> t m a  -- iterTM
--
-- \>\>\> :t streamFold Control.return effect
-- (Control.Monad m, Control.Functor f, Control.Functor g) =>
--     (f (Stream g m r) %1-> Stream g m r) -> Stream f m r %1-> Stream g m r
--
-- \>\>\> :t \f -> streamFold Control.return effect (wrap . f)
-- (Control.Monad m, Control.Functor f, Control.Functor g) =>
--     (f (Stream g m a) %1-> g (Stream g m a))
--     -> Stream f m a %1-> Stream g m a                 -- maps
--
-- \>\>\> :t \f -> streamFold Control.return effect (effect . Control.fmap wrap . f)
-- (Control.Monad m, Control.Functor f, Control.Functor g) =>
--     (f (Stream g m a) %1-> m (g (Stream g m a)))
--     -> Stream f m a %1-> Stream g m a                 -- mapped
--
-- @
--    streamFold done eff construct
--       = eff . iterT (Control.return . construct . Control.fmap eff) . Control.fmap done
-- @
streamFold ::
  (Control.Functor f, Control.Monad m) =>
  (r %1 -> b) ->
  (m b %1 -> b) ->
  (f b %1 -> b) ->
  Stream f m r %1 ->
  b
streamFold :: forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
(r %1 -> b)
-> (m b %1 -> b) -> (f b %1 -> b) -> Stream f m r %1 -> b
streamFold r %1 -> b
done m b %1 -> b
theEffect f b %1 -> b
construct Stream f m r
stream =
  forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r
%1 -> (f b %1 -> b) -> (m b %1 -> b) -> (r %1 -> b) -> b
destroy Stream f m r
stream f b %1 -> b
construct m b %1 -> b
theEffect r %1 -> b
done
{-# INLINE streamFold #-}

-- | Specialized fold following the usage of @Control.Monad.Trans.Free@
--
-- > iterT alg = streamFold Control.return Control.join alg
-- > iterT alg = runIdentityT . iterTM (IdentityT . alg . Control.fmap runIdentityT)
iterT ::
  (Control.Functor f, Control.Monad m) =>
  (f (m a) %1 -> m a) ->
  Stream f m a %1 ->
  m a
iterT :: forall (f :: * -> *) (m :: * -> *) a.
(Functor f, Monad m) =>
(f (m a) %1 -> m a) -> Stream f m a %1 -> m a
iterT f (m a) %1 -> m a
out Stream f m a
stream = forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r
%1 -> (f b %1 -> b) -> (m b %1 -> b) -> (r %1 -> b) -> b
destroyExposed Stream f m a
stream f (m a) %1 -> m a
out forall (m :: * -> *) a. Monad m => m (m a) %1 -> m a
Control.join forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return
{-# INLINE iterT #-}

-- | Specialized fold following the usage of @Control.Monad.Trans.Free@
--
-- > iterTM alg = streamFold Control.return (Control.join . Control.lift)
-- > iterTM alg = iterT alg . hoist Control.lift
iterTM ::
  ( Control.Functor f,
    Control.Monad m,
    Control.MonadTrans t,
    Control.Monad (t m)
  ) =>
  (f (t m a) %1 -> t m a) ->
  Stream f m a %1 ->
  t m a
iterTM :: forall (f :: * -> *) (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Functor f, Monad m, MonadTrans t, Monad (t m)) =>
(f (t m a) %1 -> t m a) -> Stream f m a %1 -> t m a
iterTM f (t m a) %1 -> t m a
out Stream f m a
stream =
  forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r
%1 -> (f b %1 -> b) -> (m b %1 -> b) -> (r %1 -> b) -> b
destroyExposed Stream f m a
stream f (t m a) %1 -> t m a
out (forall (m :: * -> *) a. Monad m => m (m a) %1 -> m a
Control.join forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Control.lift) forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return
{-# INLINE iterTM #-}

-- Note. 'destroy' needs to use linear functions in its church encoding
-- to consume the stream linearly.

-- | Map a stream to its church encoding; compare @Data.List.foldr@.
--    'destroyExposed' may be more efficient in some cases when
--    applicable, but it is less safe.
--
--    @
--    destroy s construct eff done
--      = eff .
--        iterT (Control.return . construct . Control.fmap eff) .
--        Control.fmap done $ s
--    @
destroy ::
  forall f m r b.
  (Control.Functor f, Control.Monad m) =>
  Stream f m r %1 ->
  (f b %1 -> b) ->
  (m b %1 -> b) ->
  (r %1 -> b) ->
  b
destroy :: forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r
%1 -> (f b %1 -> b) -> (m b %1 -> b) -> (r %1 -> b) -> b
destroy Stream f m r
stream0 f b %1 -> b
construct m b %1 -> b
theEffect r %1 -> b
done = m b %1 -> b
theEffect (Stream f m r %1 -> m b
loop Stream f m r
stream0)
  where
    loop :: Stream f m r %1 -> m b
    loop :: Stream f m r %1 -> m b
loop Stream f m r
stream =
      Stream f m r
stream forall a b (p :: Multiplicity) (q :: Multiplicity).
a %p -> (a %p -> b) %q -> b
& \case
        Return r
r -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ r %1 -> b
done r
r
        Effect m (Stream f m r)
m -> m (Stream f m r)
m forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= Stream f m r %1 -> m b
loop
        Step f (Stream f m r)
f -> forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ f b %1 -> b
construct forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (m b %1 -> b
theEffect forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Stream f m r %1 -> m b
loop) f (Stream f m r)
f
{-# INLINEABLE destroy #-}