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

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

import qualified Control.Functor.Linear as Control
import qualified Data.Functor.Linear as Data
import Prelude.Linear (($), (.))
import qualified Prelude.Linear as 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 :> -- same fixity as streaming.:>

-- # 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 = 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
  {-# INLINEABLE 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) = 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) = 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) -> f a %1 -> f b
Data.fmap (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) = 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) -> f a %1 -> f b
Data.fmap (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 = 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 = 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
  {-# INLINEABLE (<*>) #-}

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 = 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 = 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 (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 = 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 :: * -> *) 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 = 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
  {-# INLINEABLE 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) = 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) = 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 (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) = 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 :: * -> *) 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 = 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
(<*>) = 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
(>>=) = 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
  {-# INLINEABLE (>>=) #-}

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 = 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 :: * -> *) 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 = 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 (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 = 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 (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap 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 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 = forall a b. (a %1 -> b) %1 -> a -> b
Linear.forget 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 = forall a b x. (a %1 -> b) %1 -> Of x a %1 -> Of x b
ofFmap
  {-# INLINE fmap #-}