{-# OPTIONS_GHC -Wno-name-shadowing #-}
{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LinearTypes #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE RecordWildCards #-}

module Streaming.Internal.Type
  ( -- * The 'Stream' and 'Of' types
    -- $stream
    Stream (..)
  , Of (..)
  ) where

import qualified Data.Functor.Linear as Data
import qualified Control.Functor.Linear as Control
import qualified Prelude.Linear as Linear
import Prelude.Linear (($), (.))


-- # Data Definitions
-------------------------------------------------------------------------------


{- $stream

    The 'Stream' data type is equivalent to @FreeT@ and can represent any effectful
    succession of steps, where the form of the steps or 'commands' is
    specified by the first (functor) parameter. The effects are performed
    exactly once since the monad is a @Control.Monad@ from
    <https://github.com/tweag/linear-base linear-base>.

> data Stream f m r = Step !(f (Stream f m r)) | Effect (m (Stream f m r)) | Return r

    The /producer/ concept uses the simple functor @ (a,_) @ \- or the stricter
    @ Of a _ @. Then the news at each step or layer is just: an individual item of type @a@.
    Since @Stream (Of a) m r@ is equivalent to @Pipe.Producer a m r@, much of
    the @pipes@ @Prelude@ can easily be mirrored in a @streaming@ @Prelude@. Similarly,
    a simple @Consumer a m r@ or @Parser a m r@ concept arises when the base functor is
    @ (a -> _) @ . @Stream ((->) input) m result@ consumes @input@ until it returns a
    @result@.

    To avoid breaking reasoning principles, the constructors
    should not be used directly. A pattern-match should go by way of 'inspect' \
    \- or, in the producer case, 'Streaming.Prelude.next'
-}
data Stream f m r where
  Step :: !(f (Stream f m r)) %1-> Stream f m r
  Effect :: m (Stream f m r) %1-> Stream f m r
  Return :: r %1-> Stream f m r

-- | A left-strict pair; the base functor for streams of individual elements.
data Of a b where
  (:>) :: !a -> b %1-> Of a b

infixr 5 :>


-- # Control.Monad instance for (Stream f m)
-------------------------------------------------------------------------------

-- Note: we have maintained the weakest prerequisite constraints possible.

-- Note: to consume the 'Stream f m a' in the 'Cons' case, you
-- need 'fmap' to consume the stream. This implies at minimum
-- Data.Functor m and Data.Functor m.
instance (Data.Functor m, Data.Functor f) => Data.Functor (Stream f m) where
  fmap :: (Data.Functor m, Data.Functor f) =>
    (a %1-> b) -> Stream f m a %1-> Stream f m b
  fmap :: forall a b.
(Functor m, Functor f) =>
(a %1 -> b) -> Stream f m a %1 -> Stream f m b
fmap a %1 -> b
f Stream f m a
s = (a %1 -> b) -> Stream f m a %1 -> Stream f m b
forall (m :: * -> *) (f :: * -> *) a b.
(Functor m, Functor f) =>
(a %1 -> b) -> Stream f m a %1 -> Stream f m b
fmap' a %1 -> b
f Stream f m a
s
  {-# INLINABLE fmap #-}

fmap' :: (Data.Functor m, Data.Functor f) =>
  (a %1-> b) -> Stream f m a %1-> Stream f m b
fmap' :: forall (m :: * -> *) (f :: * -> *) a b.
(Functor m, Functor f) =>
(a %1 -> b) -> Stream f m a %1 -> Stream f m b
fmap' a %1 -> b
f (Return a
r) = b %1 -> Stream f m b
forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return (a %1 -> b
f a
r)
fmap' a %1 -> b
f (Step f (Stream f m a)
fs) = f (Stream f m b) %1 -> Stream f m b
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (f (Stream f m b) %1 -> Stream f m b)
%1 -> f (Stream f m b) %1 -> Stream f m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Stream f m a %1 -> Stream f m b)
-> f (Stream f m a) %1 -> f (Stream f m b)
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
Data.fmap ((a %1 -> b) -> Stream f m a %1 -> Stream f m b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
Data.fmap a %1 -> b
f) f (Stream f m a)
fs
fmap' a %1 -> b
f (Effect m (Stream f m a)
ms) = m (Stream f m b) %1 -> Stream f m b
forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream f m b) %1 -> Stream f m b)
%1 -> m (Stream f m b) %1 -> Stream f m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Stream f m a %1 -> Stream f m b)
-> m (Stream f m a) %1 -> m (Stream f m b)
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
Data.fmap ((a %1 -> b) -> Stream f m a %1 -> Stream f m b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
Data.fmap a %1 -> b
f) m (Stream f m a)
ms

-- Note: the 'Control.Functor f' instance is needed.
-- Weaker constraints won't do.
instance (Control.Functor m, Control.Functor f) =>
  Data.Applicative (Stream f m) where
  pure :: a -> Stream f m a
  pure :: forall a. a -> Stream f m a
pure = a -> Stream f m a
forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return
  {-# INLINE pure #-}

  (<*>) :: (Control.Functor m, Control.Functor f) =>
    Stream f m (a %1-> b) %1-> Stream f m a %1-> Stream f m b
  <*> :: forall a b.
(Functor m, Functor f) =>
Stream f m (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
(<*>) Stream f m (a %1 -> b)
s1 Stream f m a
s2 = Stream f m (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
forall (m :: * -> *) (f :: * -> *) a b.
(Functor m, Functor f) =>
Stream f m (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
app Stream f m (a %1 -> b)
s1 Stream f m a
s2
  {-# INLINABLE (<*>) #-}

app :: (Control.Functor m, Control.Functor f) =>
  Stream f m (a %1-> b) %1-> Stream f m a %1-> Stream f m b
app :: forall (m :: * -> *) (f :: * -> *) a b.
(Functor m, Functor f) =>
Stream f m (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
app (Return a %1 -> b
f) Stream f m a
stream = (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap a %1 -> b
f Stream f m a
stream
app (Step f (Stream f m (a %1 -> b))
fs) Stream f m a
stream = f (Stream f m b) %1 -> Stream f m b
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (f (Stream f m b) %1 -> Stream f m b)
%1 -> f (Stream f m b) %1 -> Stream f m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Stream f m (a %1 -> b) %1 -> Stream f m b)
%1 -> f (Stream f m (a %1 -> b)) %1 -> f (Stream f m b)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (Stream f m (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
forall (f :: * -> *) a b.
Applicative f =>
f (a %1 -> b) %1 -> f a %1 -> f b
Data.<*> Stream f m a
stream) f (Stream f m (a %1 -> b))
fs
app (Effect m (Stream f m (a %1 -> b))
ms) Stream f m a
stream = m (Stream f m b) %1 -> Stream f m b
forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream f m b) %1 -> Stream f m b)
%1 -> m (Stream f m b) %1 -> Stream f m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Stream f m (a %1 -> b) %1 -> Stream f m b)
%1 -> m (Stream f m (a %1 -> b)) %1 -> m (Stream f m b)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (Stream f m (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
forall (f :: * -> *) a b.
Applicative f =>
f (a %1 -> b) %1 -> f a %1 -> f b
Data.<*> Stream f m a
stream) m (Stream f m (a %1 -> b))
ms



instance (Control.Functor m, Control.Functor f) =>
  Control.Functor (Stream f m) where
  fmap :: (Data.Functor m, Data.Functor f) =>
    (a %1-> b) %1-> Stream f m a %1-> Stream f m b
  fmap :: forall a b.
(Functor m, Functor f) =>
(a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
fmap a %1 -> b
f Stream f m a
s = (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
forall (m :: * -> *) (f :: * -> *) a b.
(Functor m, Functor f) =>
(a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
fmap'' a %1 -> b
f Stream f m a
s
  {-# INLINABLE fmap #-}

fmap'' :: (Control.Functor m, Control.Functor f) =>
  (a %1-> b) %1-> Stream f m a %1-> Stream f m b
fmap'' :: forall (m :: * -> *) (f :: * -> *) a b.
(Functor m, Functor f) =>
(a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
fmap'' a %1 -> b
f (Return a
r) = b %1 -> Stream f m b
forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return (a %1 -> b
f a
r)
fmap'' a %1 -> b
f (Step f (Stream f m a)
fs) = f (Stream f m b) %1 -> Stream f m b
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (f (Stream f m b) %1 -> Stream f m b)
%1 -> f (Stream f m b) %1 -> Stream f m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Stream f m a %1 -> Stream f m b)
%1 -> f (Stream f m a) %1 -> f (Stream f m b)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap ((a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap a %1 -> b
f) f (Stream f m a)
fs
fmap'' a %1 -> b
f (Effect m (Stream f m a)
ms) = m (Stream f m b) %1 -> Stream f m b
forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream f m b) %1 -> Stream f m b)
%1 -> m (Stream f m b) %1 -> Stream f m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Stream f m a %1 -> Stream f m b)
%1 -> m (Stream f m a) %1 -> m (Stream f m b)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap ((a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap a %1 -> b
f) m (Stream f m a)
ms


instance (Control.Functor m, Control.Functor f) =>
  Control.Applicative (Stream f m) where
  pure :: a %1-> Stream f m a
  pure :: forall a. a %1 -> Stream f m a
pure = a %1 -> Stream f m a
forall r (f :: * -> *) (m :: * -> *). r -> Stream f m r
Return
  {-# INLINE pure #-}

  (<*>) :: (Control.Functor m, Control.Functor f) =>
    Stream f m (a %1-> b) %1-> Stream f m a %1-> Stream f m b
  <*> :: forall a b.
(Functor m, Functor f) =>
Stream f m (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
(<*>) = Stream f m (a %1 -> b) %1 -> Stream f m a %1 -> Stream f m b
forall (f :: * -> *) a b.
Applicative f =>
f (a %1 -> b) %1 -> f a %1 -> f b
(Data.<*>)
  {-# INLINE (<*>) #-}

instance (Control.Functor m, Control.Functor f) =>
  Control.Monad (Stream f m) where
  (>>=) :: Stream f m a %1-> (a %1-> Stream f m b) %1-> Stream f m b
  >>= :: forall a b.
Stream f m a %1 -> (a %1 -> Stream f m b) %1 -> Stream f m b
(>>=) = Stream f m a %1 -> (a %1 -> Stream f m b) %1 -> Stream f m b
forall (m :: * -> *) (f :: * -> *) a b.
(Functor m, Functor f) =>
Stream f m a %1 -> (a %1 -> Stream f m b) %1 -> Stream f m b
bind
  {-# INLINABLE (>>=) #-}

bind :: (Control.Functor m, Control.Functor f) =>
  Stream f m a %1-> (a %1-> Stream f m b) %1-> Stream f m b
bind :: forall (m :: * -> *) (f :: * -> *) a b.
(Functor m, Functor f) =>
Stream f m a %1 -> (a %1 -> Stream f m b) %1 -> Stream f m b
bind (Return a
a) a %1 -> Stream f m b
f = a %1 -> Stream f m b
f a
a
bind (Step f (Stream f m a)
fs) a %1 -> Stream f m b
f = f (Stream f m b) %1 -> Stream f m b
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (f (Stream f m b) %1 -> Stream f m b)
%1 -> f (Stream f m b) %1 -> Stream f m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Stream f m a %1 -> Stream f m b)
%1 -> f (Stream f m a) %1 -> f (Stream f m b)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (Stream f m a %1 -> (a %1 -> Stream f m b) %1 -> Stream f m b
forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= a %1 -> Stream f m b
f) f (Stream f m a)
fs
bind (Effect m (Stream f m a)
ms) a %1 -> Stream f m b
f = m (Stream f m b) %1 -> Stream f m b
forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream f m b) %1 -> Stream f m b)
%1 -> m (Stream f m b) %1 -> Stream f m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Stream f m a %1 -> Stream f m b)
%1 -> m (Stream f m a) %1 -> m (Stream f m b)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap (Stream f m a %1 -> (a %1 -> Stream f m b) %1 -> Stream f m b
forall (m :: * -> *) a b.
Monad m =>
m a %1 -> (a %1 -> m b) %1 -> m b
Control.>>= a %1 -> Stream f m b
f) m (Stream f m a)
ms


-- # MonadTrans for (Stream f m)
-------------------------------------------------------------------------------

instance Control.Functor f => Control.MonadTrans (Stream f) where
  lift :: (Control.Functor m, Control.Functor f) => m a %1-> Stream f m a
  lift :: forall (m :: * -> *) a.
(Functor m, Functor f) =>
m a %1 -> Stream f m a
lift = m (Stream f m a) %1 -> Stream f m a
forall (m :: * -> *) (f :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream f m a) %1 -> Stream f m a)
%1 -> (m a %1 -> m (Stream f m a)) %1 -> m a %1 -> Stream f m a
forall b c a. (b %1 -> c) %1 -> (a %1 -> b) %1 -> a %1 -> c
. (a %1 -> Stream f m a) %1 -> m a %1 -> m (Stream f m a)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap a %1 -> Stream f m a
forall (m :: * -> *) a. Monad m => a %1 -> m a
Control.return
  {-# INLINE lift #-}


-- # Control.Functor for (Of)
-------------------------------------------------------------------------------

ofFmap :: (a %1-> b) %1-> (Of x a) %1-> (Of x b)
ofFmap :: forall a b x. (a %1 -> b) %1 -> Of x a %1 -> Of x b
ofFmap a %1 -> b
f (x
a :> a
b) = x
a x -> b %1 -> Of x b
forall a b. a -> b -> Of a b
:> a %1 -> b
f a
b
{-# INLINE ofFmap #-}

instance Data.Functor (Of a) where
  fmap :: forall a b. (a %1 -> b) -> Of a a %1 -> Of a b
fmap = ((a %1 -> b) %1 -> Of a a %1 -> Of a b)
%1 -> (a %1 -> b) -> Of a a %1 -> Of a b
forall a b. (a %1 -> b) %1 -> a -> b
Linear.forget (a %1 -> b) %1 -> Of a a %1 -> Of a b
forall a b x. (a %1 -> b) %1 -> Of x a %1 -> Of x b
ofFmap
  {-# INLINE fmap #-}

instance Control.Functor (Of a) where
  fmap :: forall a b. (a %1 -> b) %1 -> Of a a %1 -> Of a b
fmap = (a %1 -> b) %1 -> Of a a %1 -> Of a b
forall a b x. (a %1 -> b) %1 -> Of x a %1 -> Of x b
ofFmap
  {-# INLINE fmap #-}