{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DerivingVia #-}

module Data.Stream.Filter where

-- base
import Control.Applicative (Alternative (..))
import Control.Category (Category (..))
import Control.Monad (forM, join)
import Data.Functor ((<&>))
import Data.Functor.Compose (Compose (..))
import Prelude hiding (filter, id, (.))

-- witherable
import Witherable (Filterable (..), Witherable (..))

-- semialign
import Data.Align (Align (..), Semialign (..))

-- automaton
import Data.Stream (StreamT (..), constM)
import Data.Stream.Result (unzipResult)

{- | A stream that filters or traverses its output using a type operator @f@.

When @f@ is 'Maybe', then @'FilterStream' 'Maybe' a@ can filter in the sense that on a given step there might not be an output.

@f@ can also be a type that allows multiple positions, such as lists, or 'NonEmpty'.
In this case, 'FilterStream' branches out and can explore multiple outputs at the same time.
(It keeps a single state, though.)
-}
newtype FilterStream m f a = FilterStream
  { forall (m :: Type -> Type) (f :: Type -> Type) a.
FilterStream m f a -> StreamT m (f a)
getFilterStream :: StreamT m (f a)
  -- ^ Interpret a 'FilterStream'.
  --   For instance if @f = 'Maybe'@, the resulting stream will output 'Nothing' whenever there is no output of the 'FilterStream'.
  }
  deriving ((forall a b. (a -> b) -> FilterStream m f a -> FilterStream m f b)
-> (forall a b. a -> FilterStream m f b -> FilterStream m f a)
-> Functor (FilterStream m f)
forall a b. a -> FilterStream m f b -> FilterStream m f a
forall a b. (a -> b) -> FilterStream m f a -> FilterStream m f b
forall (f :: Type -> Type).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Functor m, Functor f) =>
a -> FilterStream m f b -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Functor m, Functor f) =>
(a -> b) -> FilterStream m f a -> FilterStream m f b
$cfmap :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Functor m, Functor f) =>
(a -> b) -> FilterStream m f a -> FilterStream m f b
fmap :: forall a b. (a -> b) -> FilterStream m f a -> FilterStream m f b
$c<$ :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Functor m, Functor f) =>
a -> FilterStream m f b -> FilterStream m f a
<$ :: forall a b. a -> FilterStream m f b -> FilterStream m f a
Functor, (forall m. Monoid m => FilterStream m f m -> m)
-> (forall m a. Monoid m => (a -> m) -> FilterStream m f a -> m)
-> (forall m a. Monoid m => (a -> m) -> FilterStream m f a -> m)
-> (forall a b. (a -> b -> b) -> b -> FilterStream m f a -> b)
-> (forall a b. (a -> b -> b) -> b -> FilterStream m f a -> b)
-> (forall b a. (b -> a -> b) -> b -> FilterStream m f a -> b)
-> (forall b a. (b -> a -> b) -> b -> FilterStream m f a -> b)
-> (forall a. (a -> a -> a) -> FilterStream m f a -> a)
-> (forall a. (a -> a -> a) -> FilterStream m f a -> a)
-> (forall a. FilterStream m f a -> [a])
-> (forall a. FilterStream m f a -> Bool)
-> (forall a. FilterStream m f a -> Int)
-> (forall a. Eq a => a -> FilterStream m f a -> Bool)
-> (forall a. Ord a => FilterStream m f a -> a)
-> (forall a. Ord a => FilterStream m f a -> a)
-> (forall a. Num a => FilterStream m f a -> a)
-> (forall a. Num a => FilterStream m f a -> a)
-> Foldable (FilterStream m f)
forall a. Eq a => a -> FilterStream m f a -> Bool
forall a. Num a => FilterStream m f a -> a
forall a. Ord a => FilterStream m f a -> a
forall m. Monoid m => FilterStream m f m -> m
forall a. FilterStream m f a -> Bool
forall a. FilterStream m f a -> Int
forall a. FilterStream m f a -> [a]
forall a. (a -> a -> a) -> FilterStream m f a -> a
forall m a. Monoid m => (a -> m) -> FilterStream m f a -> m
forall b a. (b -> a -> b) -> b -> FilterStream m f a -> b
forall a b. (a -> b -> b) -> b -> FilterStream m f a -> b
forall (t :: Type -> Type).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f, Eq a) =>
a -> FilterStream m f a -> Bool
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f, Num a) =>
FilterStream m f a -> a
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f, Ord a) =>
FilterStream m f a -> a
forall (m :: Type -> Type) (f :: Type -> Type) m.
(Foldable m, Foldable f, Monoid m) =>
FilterStream m f m -> m
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
FilterStream m f a -> Bool
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
FilterStream m f a -> Int
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
FilterStream m f a -> [a]
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
(a -> a -> a) -> FilterStream m f a -> a
forall (m :: Type -> Type) (f :: Type -> Type) m a.
(Foldable m, Foldable f, Monoid m) =>
(a -> m) -> FilterStream m f a -> m
forall (m :: Type -> Type) (f :: Type -> Type) b a.
(Foldable m, Foldable f) =>
(b -> a -> b) -> b -> FilterStream m f a -> b
forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Foldable m, Foldable f) =>
(a -> b -> b) -> b -> FilterStream m f a -> b
$cfold :: forall (m :: Type -> Type) (f :: Type -> Type) m.
(Foldable m, Foldable f, Monoid m) =>
FilterStream m f m -> m
fold :: forall m. Monoid m => FilterStream m f m -> m
$cfoldMap :: forall (m :: Type -> Type) (f :: Type -> Type) m a.
(Foldable m, Foldable f, Monoid m) =>
(a -> m) -> FilterStream m f a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> FilterStream m f a -> m
$cfoldMap' :: forall (m :: Type -> Type) (f :: Type -> Type) m a.
(Foldable m, Foldable f, Monoid m) =>
(a -> m) -> FilterStream m f a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> FilterStream m f a -> m
$cfoldr :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Foldable m, Foldable f) =>
(a -> b -> b) -> b -> FilterStream m f a -> b
foldr :: forall a b. (a -> b -> b) -> b -> FilterStream m f a -> b
$cfoldr' :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Foldable m, Foldable f) =>
(a -> b -> b) -> b -> FilterStream m f a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> FilterStream m f a -> b
$cfoldl :: forall (m :: Type -> Type) (f :: Type -> Type) b a.
(Foldable m, Foldable f) =>
(b -> a -> b) -> b -> FilterStream m f a -> b
foldl :: forall b a. (b -> a -> b) -> b -> FilterStream m f a -> b
$cfoldl' :: forall (m :: Type -> Type) (f :: Type -> Type) b a.
(Foldable m, Foldable f) =>
(b -> a -> b) -> b -> FilterStream m f a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> FilterStream m f a -> b
$cfoldr1 :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
(a -> a -> a) -> FilterStream m f a -> a
foldr1 :: forall a. (a -> a -> a) -> FilterStream m f a -> a
$cfoldl1 :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
(a -> a -> a) -> FilterStream m f a -> a
foldl1 :: forall a. (a -> a -> a) -> FilterStream m f a -> a
$ctoList :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
FilterStream m f a -> [a]
toList :: forall a. FilterStream m f a -> [a]
$cnull :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
FilterStream m f a -> Bool
null :: forall a. FilterStream m f a -> Bool
$clength :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f) =>
FilterStream m f a -> Int
length :: forall a. FilterStream m f a -> Int
$celem :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f, Eq a) =>
a -> FilterStream m f a -> Bool
elem :: forall a. Eq a => a -> FilterStream m f a -> Bool
$cmaximum :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f, Ord a) =>
FilterStream m f a -> a
maximum :: forall a. Ord a => FilterStream m f a -> a
$cminimum :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f, Ord a) =>
FilterStream m f a -> a
minimum :: forall a. Ord a => FilterStream m f a -> a
$csum :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f, Num a) =>
FilterStream m f a -> a
sum :: forall a. Num a => FilterStream m f a -> a
$cproduct :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Foldable m, Foldable f, Num a) =>
FilterStream m f a -> a
product :: forall a. Num a => FilterStream m f a -> a
Foldable, Functor (FilterStream m f)
Foldable (FilterStream m f)
(Functor (FilterStream m f), Foldable (FilterStream m f)) =>
(forall (f :: Type -> Type) a b.
 Applicative f =>
 (a -> f b) -> FilterStream m f a -> f (FilterStream m f b))
-> (forall (f :: Type -> Type) a.
    Applicative f =>
    FilterStream m f (f a) -> f (FilterStream m f a))
-> (forall (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> FilterStream m f a -> m (FilterStream m f b))
-> (forall (m :: Type -> Type) a.
    Monad m =>
    FilterStream m f (m a) -> m (FilterStream m f a))
-> Traversable (FilterStream m f)
forall (t :: Type -> Type).
(Functor t, Foldable t) =>
(forall (f :: Type -> Type) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: Type -> Type) a.
    Applicative f =>
    t (f a) -> f (t a))
-> (forall (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: Type -> Type) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: Type -> Type) a.
Monad m =>
FilterStream m f (m a) -> m (FilterStream m f a)
forall (f :: Type -> Type) a.
Applicative f =>
FilterStream m f (f a) -> f (FilterStream m f a)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> FilterStream m f a -> m (FilterStream m f b)
forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> FilterStream m f a -> f (FilterStream m f b)
forall (m :: Type -> Type) (f :: Type -> Type).
(Traversable m, Traversable f) =>
Functor (FilterStream m f)
forall (m :: Type -> Type) (f :: Type -> Type).
(Traversable m, Traversable f) =>
Foldable (FilterStream m f)
forall (m :: Type -> Type) (f :: Type -> Type) (m :: Type -> Type)
       a.
(Traversable m, Traversable f, Monad m) =>
FilterStream m f (m a) -> m (FilterStream m f a)
forall (m :: Type -> Type) (f :: Type -> Type) (f :: Type -> Type)
       a.
(Traversable m, Traversable f, Applicative f) =>
FilterStream m f (f a) -> f (FilterStream m f a)
forall (m :: Type -> Type) (f :: Type -> Type) (m :: Type -> Type)
       a b.
(Traversable m, Traversable f, Monad m) =>
(a -> m b) -> FilterStream m f a -> m (FilterStream m f b)
forall (m :: Type -> Type) (f :: Type -> Type) (f :: Type -> Type)
       a b.
(Traversable m, Traversable f, Applicative f) =>
(a -> f b) -> FilterStream m f a -> f (FilterStream m f b)
$ctraverse :: forall (m :: Type -> Type) (f :: Type -> Type) (f :: Type -> Type)
       a b.
(Traversable m, Traversable f, Applicative f) =>
(a -> f b) -> FilterStream m f a -> f (FilterStream m f b)
traverse :: forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> FilterStream m f a -> f (FilterStream m f b)
$csequenceA :: forall (m :: Type -> Type) (f :: Type -> Type) (f :: Type -> Type)
       a.
(Traversable m, Traversable f, Applicative f) =>
FilterStream m f (f a) -> f (FilterStream m f a)
sequenceA :: forall (f :: Type -> Type) a.
Applicative f =>
FilterStream m f (f a) -> f (FilterStream m f a)
$cmapM :: forall (m :: Type -> Type) (f :: Type -> Type) (m :: Type -> Type)
       a b.
(Traversable m, Traversable f, Monad m) =>
(a -> m b) -> FilterStream m f a -> m (FilterStream m f b)
mapM :: forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> FilterStream m f a -> m (FilterStream m f b)
$csequence :: forall (m :: Type -> Type) (f :: Type -> Type) (m :: Type -> Type)
       a.
(Traversable m, Traversable f, Monad m) =>
FilterStream m f (m a) -> m (FilterStream m f a)
sequence :: forall (m :: Type -> Type) a.
Monad m =>
FilterStream m f (m a) -> m (FilterStream m f a)
Traversable)
  deriving (Functor (FilterStream m f)
Functor (FilterStream m f) =>
(forall a. a -> FilterStream m f a)
-> (forall a b.
    FilterStream m f (a -> b)
    -> FilterStream m f a -> FilterStream m f b)
-> (forall a b c.
    (a -> b -> c)
    -> FilterStream m f a -> FilterStream m f b -> FilterStream m f c)
-> (forall a b.
    FilterStream m f a -> FilterStream m f b -> FilterStream m f b)
-> (forall a b.
    FilterStream m f a -> FilterStream m f b -> FilterStream m f a)
-> Applicative (FilterStream m f)
forall a. a -> FilterStream m f a
forall a b.
FilterStream m f a -> FilterStream m f b -> FilterStream m f a
forall a b.
FilterStream m f a -> FilterStream m f b -> FilterStream m f b
forall a b.
FilterStream m f (a -> b)
-> FilterStream m f a -> FilterStream m f b
forall a b c.
(a -> b -> c)
-> FilterStream m f a -> FilterStream m f b -> FilterStream m f c
forall (f :: Type -> Type).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: Type -> Type) (f :: Type -> Type).
(Applicative m, Applicative f) =>
Functor (FilterStream m f)
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Applicative m, Applicative f) =>
a -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Applicative m, Applicative f) =>
FilterStream m f a -> FilterStream m f b -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Applicative m, Applicative f) =>
FilterStream m f a -> FilterStream m f b -> FilterStream m f b
forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Applicative m, Applicative f) =>
FilterStream m f (a -> b)
-> FilterStream m f a -> FilterStream m f b
forall (m :: Type -> Type) (f :: Type -> Type) a b c.
(Applicative m, Applicative f) =>
(a -> b -> c)
-> FilterStream m f a -> FilterStream m f b -> FilterStream m f c
$cpure :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Applicative m, Applicative f) =>
a -> FilterStream m f a
pure :: forall a. a -> FilterStream m f a
$c<*> :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Applicative m, Applicative f) =>
FilterStream m f (a -> b)
-> FilterStream m f a -> FilterStream m f b
<*> :: forall a b.
FilterStream m f (a -> b)
-> FilterStream m f a -> FilterStream m f b
$cliftA2 :: forall (m :: Type -> Type) (f :: Type -> Type) a b c.
(Applicative m, Applicative f) =>
(a -> b -> c)
-> FilterStream m f a -> FilterStream m f b -> FilterStream m f c
liftA2 :: forall a b c.
(a -> b -> c)
-> FilterStream m f a -> FilterStream m f b -> FilterStream m f c
$c*> :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Applicative m, Applicative f) =>
FilterStream m f a -> FilterStream m f b -> FilterStream m f b
*> :: forall a b.
FilterStream m f a -> FilterStream m f b -> FilterStream m f b
$c<* :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Applicative m, Applicative f) =>
FilterStream m f a -> FilterStream m f b -> FilterStream m f a
<* :: forall a b.
FilterStream m f a -> FilterStream m f b -> FilterStream m f a
Applicative) via Compose (StreamT m) f
  deriving (Applicative (FilterStream m f)
Applicative (FilterStream m f) =>
(forall a. FilterStream m f a)
-> (forall a.
    FilterStream m f a -> FilterStream m f a -> FilterStream m f a)
-> (forall a. FilterStream m f a -> FilterStream m f [a])
-> (forall a. FilterStream m f a -> FilterStream m f [a])
-> Alternative (FilterStream m f)
forall a. FilterStream m f a
forall a. FilterStream m f a -> FilterStream m f [a]
forall a.
FilterStream m f a -> FilterStream m f a -> FilterStream m f a
forall (f :: Type -> Type).
Applicative f =>
(forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall (m :: Type -> Type) (f :: Type -> Type).
(Alternative m, Applicative f) =>
Applicative (FilterStream m f)
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Alternative m, Applicative f) =>
FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Alternative m, Applicative f) =>
FilterStream m f a -> FilterStream m f [a]
forall (m :: Type -> Type) (f :: Type -> Type) a.
(Alternative m, Applicative f) =>
FilterStream m f a -> FilterStream m f a -> FilterStream m f a
$cempty :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Alternative m, Applicative f) =>
FilterStream m f a
empty :: forall a. FilterStream m f a
$c<|> :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Alternative m, Applicative f) =>
FilterStream m f a -> FilterStream m f a -> FilterStream m f a
<|> :: forall a.
FilterStream m f a -> FilterStream m f a -> FilterStream m f a
$csome :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Alternative m, Applicative f) =>
FilterStream m f a -> FilterStream m f [a]
some :: forall a. FilterStream m f a -> FilterStream m f [a]
$cmany :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Alternative m, Applicative f) =>
FilterStream m f a -> FilterStream m f [a]
many :: forall a. FilterStream m f a -> FilterStream m f [a]
Alternative) via Compose (StreamT m) f

-- | Use a filtered value to create a 'FilterStream'.
constFilter :: (Applicative m) => f a -> FilterStream m f a
constFilter :: forall (m :: Type -> Type) (f :: Type -> Type) a.
Applicative m =>
f a -> FilterStream m f a
constFilter = StreamT m (f a) -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a.
StreamT m (f a) -> FilterStream m f a
FilterStream (StreamT m (f a) -> FilterStream m f a)
-> (f a -> StreamT m (f a)) -> f a -> FilterStream m f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. f a -> StreamT m (f a)
forall a. a -> StreamT m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure

-- | Use an effectful filtered value to create a 'FilterStream'.
filterM :: (Functor m) => m (f a) -> FilterStream m f a
filterM :: forall (m :: Type -> Type) (f :: Type -> Type) a.
Functor m =>
m (f a) -> FilterStream m f a
filterM = StreamT m (f a) -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a.
StreamT m (f a) -> FilterStream m f a
FilterStream (StreamT m (f a) -> FilterStream m f a)
-> (m (f a) -> StreamT m (f a)) -> m (f a) -> FilterStream m f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. m (f a) -> StreamT m (f a)
forall (m :: Type -> Type) a. Functor m => m a -> StreamT m a
constM

-- | Filter a stream according to a predicate.
filterS :: (Monad m, Witherable f, Applicative f) => (a -> Bool) -> FilterStream m f a -> FilterStream m f a
filterS :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Monad m, Witherable f, Applicative f) =>
(a -> Bool) -> FilterStream m f a -> FilterStream m f a
filterS a -> Bool
f = StreamT m (f a) -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a.
StreamT m (f a) -> FilterStream m f a
FilterStream (StreamT m (f a) -> FilterStream m f a)
-> (FilterStream m f a -> StreamT m (f a))
-> FilterStream m f a
-> FilterStream m f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (f a -> f a) -> StreamT m (f a) -> StreamT m (f a)
forall a b. (a -> b) -> StreamT m a -> StreamT m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> Bool) -> f a -> f a
forall a. (a -> Bool) -> f a -> f a
forall (f :: Type -> Type) a.
Filterable f =>
(a -> Bool) -> f a -> f a
filter a -> Bool
f) (StreamT m (f a) -> StreamT m (f a))
-> (FilterStream m f a -> StreamT m (f a))
-> FilterStream m f a
-> StreamT m (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. FilterStream m f a -> StreamT m (f a)
forall (m :: Type -> Type) (f :: Type -> Type) a.
FilterStream m f a -> StreamT m (f a)
getFilterStream

{- | Given an @f@-effect in the step function of a stream, push it into the output type.

This works by internally tracking the @f@ effects in the state, and at the same time joining them in the output.

For example, if @f@ is lists, and @stream :: StreamT (Compose m []) a@ creates a 2-element list at some point,
the internal state of @streamFilter stream@ will split into two, and there are two outputs.

Likewise, if @f@ is 'Maybe', and a 'Nothing' occurs at some point, then this automaton is deactivated forever.
-}
streamFilter :: (Monad f, Traversable f, Monad m) => StreamT (Compose m f) a -> FilterStream m f a
streamFilter :: forall (f :: Type -> Type) (m :: Type -> Type) a.
(Monad f, Traversable f, Monad m) =>
StreamT (Compose m f) a -> FilterStream m f a
streamFilter StreamT {s
state :: s
state :: ()
state, s -> Compose m f (Result s a)
step :: s -> Compose m f (Result s a)
step :: ()
step} =
  StreamT m (f a) -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a.
StreamT m (f a) -> FilterStream m f a
FilterStream (StreamT m (f a) -> FilterStream m f a)
-> StreamT m (f a) -> FilterStream m f a
forall a b. (a -> b) -> a -> b
$
    StreamT
      { state :: f s
state = s -> f s
forall a. a -> f a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure s
state
      , step :: f s -> m (Result (f s) (f a))
step = \f s
states -> f (Result s a) -> Result (f s) (f a)
forall (f :: Type -> Type) s a.
Functor f =>
f (Result s a) -> Result (f s) (f a)
unzipResult (f (Result s a) -> Result (f s) (f a))
-> (f (f (Result s a)) -> f (Result s a))
-> f (f (Result s a))
-> Result (f s) (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. f (f (Result s a)) -> f (Result s a)
forall (m :: Type -> Type) a. Monad m => m (m a) -> m a
join (f (f (Result s a)) -> Result (f s) (f a))
-> m (f (f (Result s a))) -> m (Result (f s) (f a))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> f s -> (s -> m (f (Result s a))) -> m (f (f (Result s a)))
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM f s
states (Compose m f (Result s a) -> m (f (Result s a))
forall {k1} {k2} (f :: k1 -> Type) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose m f (Result s a) -> m (f (Result s a)))
-> (s -> Compose m f (Result s a)) -> s -> m (f (Result s a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. s -> Compose m f (Result s a)
step)
      }

-- | Given a branching stream, concatenate all branches at every step.
runListS :: (Monad m) => StreamT (Compose m []) a -> StreamT m [a]
runListS :: forall (m :: Type -> Type) a.
Monad m =>
StreamT (Compose m []) a -> StreamT m [a]
runListS = FilterStream m [] a -> StreamT m [a]
forall (m :: Type -> Type) (f :: Type -> Type) a.
FilterStream m f a -> StreamT m (f a)
getFilterStream (FilterStream m [] a -> StreamT m [a])
-> (StreamT (Compose m []) a -> FilterStream m [] a)
-> StreamT (Compose m []) a
-> StreamT m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. StreamT (Compose m []) a -> FilterStream m [] a
forall (f :: Type -> Type) (m :: Type -> Type) a.
(Monad f, Traversable f, Monad m) =>
StreamT (Compose m f) a -> FilterStream m f a
streamFilter

-- | Lift a regular 'StreamT' (which doesn't filter) to a 'FilterStream'.
liftFilter :: (Monad m, Applicative f) => StreamT m a -> FilterStream m f a
liftFilter :: forall (m :: Type -> Type) (f :: Type -> Type) a.
(Monad m, Applicative f) =>
StreamT m a -> FilterStream m f a
liftFilter = StreamT m (f a) -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a.
StreamT m (f a) -> FilterStream m f a
FilterStream (StreamT m (f a) -> FilterStream m f a)
-> (StreamT m a -> StreamT m (f a))
-> StreamT m a
-> FilterStream m f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a -> f a) -> StreamT m a -> StreamT m (f a)
forall a b. (a -> b) -> StreamT m a -> StreamT m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> f a
forall a. a -> f a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure

instance (Functor m, Filterable f) => Filterable (FilterStream m f) where
  mapMaybe :: forall a b.
(a -> Maybe b) -> FilterStream m f a -> FilterStream m f b
mapMaybe a -> Maybe b
f (FilterStream StreamT m (f a)
automaton) = StreamT m (f b) -> FilterStream m f b
forall (m :: Type -> Type) (f :: Type -> Type) a.
StreamT m (f a) -> FilterStream m f a
FilterStream (StreamT m (f b) -> FilterStream m f b)
-> StreamT m (f b) -> FilterStream m f b
forall a b. (a -> b) -> a -> b
$ StreamT m (f a)
automaton StreamT m (f a) -> (f a -> f b) -> StreamT m (f b)
forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> (a -> Maybe b) -> f a -> f b
forall a b. (a -> Maybe b) -> f a -> f b
forall (f :: Type -> Type) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe a -> Maybe b
f

instance (Functor m, Traversable m, Filterable f, Traversable f) => Witherable (FilterStream m f)

-- | Run two streams in parallel and 'align' their outputs.
instance (Semialign f, Applicative m) => Semialign (FilterStream m f) where
  align :: forall a b.
FilterStream m f a
-> FilterStream m f b -> FilterStream m f (These a b)
align FilterStream m f a
a FilterStream m f b
b = StreamT m (f (These a b)) -> FilterStream m f (These a b)
forall (m :: Type -> Type) (f :: Type -> Type) a.
StreamT m (f a) -> FilterStream m f a
FilterStream (StreamT m (f (These a b)) -> FilterStream m f (These a b))
-> StreamT m (f (These a b)) -> FilterStream m f (These a b)
forall a b. (a -> b) -> a -> b
$ f a -> f b -> f (These a b)
forall a b. f a -> f b -> f (These a b)
forall (f :: Type -> Type) a b.
Semialign f =>
f a -> f b -> f (These a b)
align (f a -> f b -> f (These a b))
-> StreamT m (f a) -> StreamT m (f b -> f (These a b))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> FilterStream m f a -> StreamT m (f a)
forall (m :: Type -> Type) (f :: Type -> Type) a.
FilterStream m f a -> StreamT m (f a)
getFilterStream FilterStream m f a
a StreamT m (f b -> f (These a b))
-> StreamT m (f b) -> StreamT m (f (These a b))
forall a b. StreamT m (a -> b) -> StreamT m a -> StreamT m b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> FilterStream m f b -> StreamT m (f b)
forall (m :: Type -> Type) (f :: Type -> Type) a.
FilterStream m f a -> StreamT m (f a)
getFilterStream FilterStream m f b
b

instance (Align f, Applicative m) => Align (FilterStream m f) where
  nil :: forall a. FilterStream m f a
nil = f a -> FilterStream m f a
forall (m :: Type -> Type) (f :: Type -> Type) a.
Applicative m =>
f a -> FilterStream m f a
constFilter f a
forall a. f a
forall (f :: Type -> Type) a. Align f => f a
nil