module Data.Stream.Except where

-- base
import Control.Category ((>>>))
import Control.Monad (ap)
import Data.Bifunctor (bimap)
import Data.Function ((&))
import Data.Functor ((<&>))
import Data.Void

-- transformers
import Control.Monad.Trans.Class
import Control.Monad.Trans.Except

-- mmorph
import Control.Monad.Morph (MFunctor, hoist)

-- selective
import Control.Selective

-- automaton
import Data.Stream (foreverExcept)
import Data.Stream.Optimized as OptimizedStreamT (OptimizedStreamT, applyExcept, constM, hoist', selectExcept)
import Data.Stream.Optimized qualified as StreamOptimized
import Data.Stream.Recursive (Recursive (..))
import Data.Stream.Recursive as Recursive (hoist')
import Data.Stream.Recursive.Except
import Data.Stream.Result

{- | A stream that can terminate with an exception.

In @automaton@, such streams mainly serve as a vehicle to bring control flow to 'Data.Automaton.Trans.Except.AutomatonExcept'
(which is based on 'StreamExcept'), and the docs there apply here as well.

'StreamExcept' is not only a 'Monad', it also has more efficient 'Selective', 'Applicative', and 'Functor' interfaces.
-}
data StreamExcept a m e
  = -- | When using '>>=', this encoding will be used.
    RecursiveExcept (Recursive (ExceptT e m) a)
  | -- | This is usually the faster encoding, as it can be optimized by GHC.
    CoalgebraicExcept (OptimizedStreamT (ExceptT e m) a)

-- | Apply a function to the output of the stream
mapOutput :: (Functor m) => (a -> b) -> StreamExcept a m e -> StreamExcept b m e
mapOutput :: forall (m :: Type -> Type) a b e.
Functor m =>
(a -> b) -> StreamExcept a m e -> StreamExcept b m e
mapOutput a -> b
f (RecursiveExcept Recursive (ExceptT e m) a
recursive) = Recursive (ExceptT e m) b -> StreamExcept b m e
forall a (m :: Type -> Type) e.
Recursive (ExceptT e m) a -> StreamExcept a m e
RecursiveExcept (Recursive (ExceptT e m) b -> StreamExcept b m e)
-> Recursive (ExceptT e m) b -> StreamExcept b m e
forall a b. (a -> b) -> a -> b
$ a -> b
f (a -> b) -> Recursive (ExceptT e m) a -> Recursive (ExceptT e m) b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Recursive (ExceptT e m) a
recursive
mapOutput a -> b
f (CoalgebraicExcept OptimizedStreamT (ExceptT e m) a
coalgebraic) = OptimizedStreamT (ExceptT e m) b -> StreamExcept b m e
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept (OptimizedStreamT (ExceptT e m) b -> StreamExcept b m e)
-> OptimizedStreamT (ExceptT e m) b -> StreamExcept b m e
forall a b. (a -> b) -> a -> b
$ a -> b
f (a -> b)
-> OptimizedStreamT (ExceptT e m) a
-> OptimizedStreamT (ExceptT e m) b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> OptimizedStreamT (ExceptT e m) a
coalgebraic

toRecursive :: (Functor m) => StreamExcept a m e -> Recursive (ExceptT e m) a
toRecursive :: forall (m :: Type -> Type) a e.
Functor m =>
StreamExcept a m e -> Recursive (ExceptT e m) a
toRecursive (RecursiveExcept Recursive (ExceptT e m) a
recursive) = Recursive (ExceptT e m) a
recursive
toRecursive (CoalgebraicExcept OptimizedStreamT (ExceptT e m) a
coalgebraic) = OptimizedStreamT (ExceptT e m) a -> Recursive (ExceptT e m) a
forall (m :: Type -> Type) a.
Functor m =>
OptimizedStreamT m a -> Recursive m a
StreamOptimized.toRecursive OptimizedStreamT (ExceptT e m) a
coalgebraic

runStreamExcept :: StreamExcept a m e -> OptimizedStreamT (ExceptT e m) a
runStreamExcept :: forall a (m :: Type -> Type) e.
StreamExcept a m e -> OptimizedStreamT (ExceptT e m) a
runStreamExcept (RecursiveExcept Recursive (ExceptT e m) a
recursive) = Recursive (ExceptT e m) a -> OptimizedStreamT (ExceptT e m) a
forall (m :: Type -> Type) a. Recursive m a -> OptimizedStreamT m a
StreamOptimized.fromRecursive Recursive (ExceptT e m) a
recursive
runStreamExcept (CoalgebraicExcept OptimizedStreamT (ExceptT e m) a
coalgebraic) = OptimizedStreamT (ExceptT e m) a
coalgebraic

stepInstant :: (Functor m) => StreamExcept a m e -> m (Either e (Result (StreamExcept a m e) a))
stepInstant :: forall (m :: Type -> Type) a e.
Functor m =>
StreamExcept a m e -> m (Either e (Result (StreamExcept a m e) a))
stepInstant = StreamExcept a m e -> OptimizedStreamT (ExceptT e m) a
forall a (m :: Type -> Type) e.
StreamExcept a m e -> OptimizedStreamT (ExceptT e m) a
runStreamExcept (StreamExcept a m e -> OptimizedStreamT (ExceptT e m) a)
-> (OptimizedStreamT (ExceptT e m) a
    -> m (Either e (Result (StreamExcept a m e) a)))
-> StreamExcept a m e
-> m (Either e (Result (StreamExcept a m e) a))
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> OptimizedStreamT (ExceptT e m) a
-> ExceptT e m (Result (OptimizedStreamT (ExceptT e m) a) a)
forall (m :: Type -> Type) a.
Functor m =>
OptimizedStreamT m a -> m (Result (OptimizedStreamT m a) a)
StreamOptimized.stepOptimizedStream (OptimizedStreamT (ExceptT e m) a
 -> ExceptT e m (Result (OptimizedStreamT (ExceptT e m) a) a))
-> (ExceptT e m (Result (OptimizedStreamT (ExceptT e m) a) a)
    -> m (Either e (Result (StreamExcept a m e) a)))
-> OptimizedStreamT (ExceptT e m) a
-> m (Either e (Result (StreamExcept a m e) a))
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> ExceptT e m (Result (OptimizedStreamT (ExceptT e m) a) a)
-> m (Either e (Result (OptimizedStreamT (ExceptT e m) a) a))
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m (Result (OptimizedStreamT (ExceptT e m) a) a)
 -> m (Either e (Result (OptimizedStreamT (ExceptT e m) a) a)))
-> (m (Either e (Result (OptimizedStreamT (ExceptT e m) a) a))
    -> m (Either e (Result (StreamExcept a m e) a)))
-> ExceptT e m (Result (OptimizedStreamT (ExceptT e m) a) a)
-> m (Either e (Result (StreamExcept a m e) a))
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Either e (Result (OptimizedStreamT (ExceptT e m) a) a)
 -> Either e (Result (StreamExcept a m e) a))
-> m (Either e (Result (OptimizedStreamT (ExceptT e m) a) a))
-> m (Either e (Result (StreamExcept a m e) a))
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Result (OptimizedStreamT (ExceptT e m) a) a
 -> Result (StreamExcept a m e) a)
-> Either e (Result (OptimizedStreamT (ExceptT e m) a) a)
-> Either e (Result (StreamExcept a m e) a)
forall a b. (a -> b) -> Either e a -> Either e b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e)
-> Result (OptimizedStreamT (ExceptT e m) a) a
-> Result (StreamExcept a m e) a
forall s1 s2 a. (s1 -> s2) -> Result s1 a -> Result s2 a
mapResultState OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept))

-- | Run all steps of the stream, discarding all output, until the exception is reached.
instance (Functor m, Foldable m) => Foldable (StreamExcept a m) where
  foldMap :: forall m a. Monoid m => (a -> m) -> StreamExcept a m a -> m
foldMap a -> m
f = StreamExcept a m a -> m (Either a (Result (StreamExcept a m a) a))
forall (m :: Type -> Type) a e.
Functor m =>
StreamExcept a m e -> m (Either e (Result (StreamExcept a m e) a))
stepInstant (StreamExcept a m a
 -> m (Either a (Result (StreamExcept a m a) a)))
-> (m (Either a (Result (StreamExcept a m a) a)) -> m)
-> StreamExcept a m a
-> m
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Either a (Result (StreamExcept a m a) a) -> m)
-> m (Either a (Result (StreamExcept a m a) a)) -> m
forall m a. Monoid m => (a -> m) -> m a -> m
forall (t :: Type -> Type) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((a -> m)
-> (Result (StreamExcept a m a) a -> m)
-> Either a (Result (StreamExcept a m a) a)
-> m
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> m
f ((Result (StreamExcept a m a) a -> m)
 -> Either a (Result (StreamExcept a m a) a) -> m)
-> (Result (StreamExcept a m a) a -> m)
-> Either a (Result (StreamExcept a m a) a)
-> m
forall a b. (a -> b) -> a -> b
$ Result (StreamExcept a m a) a -> StreamExcept a m a
forall s a. Result s a -> s
resultState (Result (StreamExcept a m a) a -> StreamExcept a m a)
-> (StreamExcept a m a -> m) -> Result (StreamExcept a m a) a -> m
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (a -> m) -> StreamExcept a m a -> m
forall m a. Monoid m => (a -> m) -> StreamExcept a m a -> m
forall (t :: Type -> Type) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f)

instance (Traversable m) => Traversable (StreamExcept a m) where
  traverse :: forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> StreamExcept a m a -> f (StreamExcept a m b)
traverse a -> f b
f StreamExcept a m a
streamExcept = Recursive (ExceptT a m) a
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
traverseRecursive (StreamExcept a m a -> Recursive (ExceptT a m) a
forall (m :: Type -> Type) a e.
Functor m =>
StreamExcept a m e -> Recursive (ExceptT e m) a
toRecursive StreamExcept a m a
streamExcept) f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
-> (f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
    -> f (StreamExcept a m b))
-> f (StreamExcept a m b)
forall a b. a -> (a -> b) -> b
& (ExceptT b m (Result (Recursive (ExceptT b m) a) a)
 -> StreamExcept a m b)
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
-> f (StreamExcept a m b)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (ExceptT b m (Result (Recursive (ExceptT b m) a) a)
-> Recursive (ExceptT b m) a
forall (m :: Type -> Type) a.
m (Result (Recursive m a) a) -> Recursive m a
Recursive (ExceptT b m (Result (Recursive (ExceptT b m) a) a)
 -> Recursive (ExceptT b m) a)
-> (Recursive (ExceptT b m) a -> StreamExcept a m b)
-> ExceptT b m (Result (Recursive (ExceptT b m) a) a)
-> StreamExcept a m b
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Recursive (ExceptT b m) a -> StreamExcept a m b
forall a (m :: Type -> Type) e.
Recursive (ExceptT e m) a -> StreamExcept a m e
RecursiveExcept)
    where
      traverseRecursive :: Recursive (ExceptT a m) a
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
traverseRecursive =
        Recursive (ExceptT a m) a
-> ExceptT a m (Result (Recursive (ExceptT a m) a) a)
forall (m :: Type -> Type) a.
Recursive m a -> m (Result (Recursive m a) a)
getRecursive
          (Recursive (ExceptT a m) a
 -> ExceptT a m (Result (Recursive (ExceptT a m) a) a))
-> (ExceptT a m (Result (Recursive (ExceptT a m) a) a)
    -> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a)))
-> Recursive (ExceptT a m) a
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> ExceptT a m (Result (Recursive (ExceptT a m) a) a)
-> m (Either a (Result (Recursive (ExceptT a m) a) a))
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT
          (ExceptT a m (Result (Recursive (ExceptT a m) a) a)
 -> m (Either a (Result (Recursive (ExceptT a m) a) a)))
-> (m (Either a (Result (Recursive (ExceptT a m) a) a))
    -> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a)))
-> ExceptT a m (Result (Recursive (ExceptT a m) a) a)
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Either a (Result (Recursive (ExceptT a m) a) a)
 -> f (Either
         b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
-> m (Either a (Result (Recursive (ExceptT a m) a) a))
-> m (f (Either
           b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> f b)
-> (Result (Recursive (ExceptT a m) a) a
    -> f (Result
            (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
-> Either a (Result (Recursive (ExceptT a m) a) a)
-> Either
     (f b)
     (f (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
forall a b c d. (a -> b) -> (c -> d) -> Either a c -> Either b d
forall (p :: Type -> Type -> Type) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> f b
f ((Recursive (ExceptT a m) a
 -> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a)))
-> Result (Recursive (ExceptT a m) a) a
-> Result
     (f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))) a
forall s1 s2 a. (s1 -> s2) -> Result s1 a -> Result s2 a
mapResultState Recursive (ExceptT a m) a
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
traverseRecursive (Result (Recursive (ExceptT a m) a) a
 -> Result
      (f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))) a)
-> (Result
      (f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))) a
    -> f (Result
            (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
-> Result (Recursive (ExceptT a m) a) a
-> f (Result
        (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (\Result {f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
resultState :: forall s a. Result s a -> s
resultState :: f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
resultState, a
output :: a
output :: forall s a. Result s a -> a
output} -> (ExceptT b m (Result (Recursive (ExceptT b m) a) a)
-> a
-> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a
forall s a. s -> a -> Result s a
Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)
 -> a
 -> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
-> f (a
      -> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
resultState) f (a
   -> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
-> ((a
     -> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
    -> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
-> f (Result
        (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> ((a
 -> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
-> a
-> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a
forall a b. (a -> b) -> a -> b
$ a
output))) (Either a (Result (Recursive (ExceptT a m) a) a)
 -> Either
      (f b)
      (f (Result
            (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
-> (Either
      (f b)
      (f (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
    -> f (Either
            b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
-> Either a (Result (Recursive (ExceptT a m) a) a)
-> f (Either
        b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Either
  (f b)
  (f (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
-> f (Either
        b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
forall (f :: Type -> Type) a b.
Functor f =>
Either (f a) (f b) -> f (Either a b)
bitraverseEither)
          (m (Either a (Result (Recursive (ExceptT a m) a) a))
 -> m (f (Either
            b
            (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))))
-> (m (f (Either
            b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
    -> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a)))
-> m (Either a (Result (Recursive (ExceptT a m) a) a))
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> m (f (Either
        b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
-> f (m (Either
           b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
forall (t :: Type -> Type) (f :: Type -> Type) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: Type -> Type) a. Applicative f => m (f a) -> f (m a)
sequenceA
          (m (f (Either
         b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
 -> f (m (Either
            b
            (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))))
-> (f (m (Either
            b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
    -> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a)))
-> m (f (Either
           b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (m (Either
      b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
 -> ExceptT b m (Result (Recursive (ExceptT b m) a) a))
-> f (m (Either
           b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)))
-> f (ExceptT b m (Result (Recursive (ExceptT b m) a) a))
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (m (Either
     b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
-> ExceptT
     b m (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either
      b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
 -> ExceptT
      b
      m
      (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
-> (ExceptT
      b m (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
    -> ExceptT b m (Result (Recursive (ExceptT b m) a) a))
-> m (Either
        b (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a))
-> ExceptT b m (Result (Recursive (ExceptT b m) a) a)
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a
 -> Result (Recursive (ExceptT b m) a) a)
-> ExceptT
     b m (Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a)
-> ExceptT b m (Result (Recursive (ExceptT b m) a) a)
forall a b. (a -> b) -> ExceptT b m a -> ExceptT b m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ExceptT b m (Result (Recursive (ExceptT b m) a) a)
 -> Recursive (ExceptT b m) a)
-> Result (ExceptT b m (Result (Recursive (ExceptT b m) a) a)) a
-> Result (Recursive (ExceptT b m) a) a
forall s1 s2 a. (s1 -> s2) -> Result s1 a -> Result s2 a
mapResultState ExceptT b m (Result (Recursive (ExceptT b m) a) a)
-> Recursive (ExceptT b m) a
forall (m :: Type -> Type) a.
m (Result (Recursive m a) a) -> Recursive m a
Recursive))
      bitraverseEither :: (Functor f) => Either (f a) (f b) -> f (Either a b)
      bitraverseEither :: forall (f :: Type -> Type) a b.
Functor f =>
Either (f a) (f b) -> f (Either a b)
bitraverseEither = (f a -> f (Either a b))
-> (f b -> f (Either a b)) -> Either (f a) (f b) -> f (Either a b)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((a -> Either a b) -> f a -> f (Either a b)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either a b
forall a b. a -> Either a b
Left) ((b -> Either a b) -> f b -> f (Either a b)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> Either a b
forall a b. b -> Either a b
Right)

instance (Functor m) => Functor (StreamExcept a m) where
  fmap :: forall a b. (a -> b) -> StreamExcept a m a -> StreamExcept a m b
fmap a -> b
f (RecursiveExcept Recursive (ExceptT a m) a
fe) = Recursive (ExceptT b m) a -> StreamExcept a m b
forall a (m :: Type -> Type) e.
Recursive (ExceptT e m) a -> StreamExcept a m e
RecursiveExcept (Recursive (ExceptT b m) a -> StreamExcept a m b)
-> Recursive (ExceptT b m) a -> StreamExcept a m b
forall a b. (a -> b) -> a -> b
$ (forall x. ExceptT a m x -> ExceptT b m x)
-> Recursive (ExceptT a m) a -> Recursive (ExceptT b m) a
forall (f :: Type -> Type) (g :: Type -> Type) a.
Functor f =>
(forall x. f x -> g x) -> Recursive f a -> Recursive g a
Recursive.hoist' ((a -> b) -> ExceptT a m x -> ExceptT b m x
forall (m :: Type -> Type) e e' a.
Functor m =>
(e -> e') -> ExceptT e m a -> ExceptT e' m a
withExceptT a -> b
f) Recursive (ExceptT a m) a
fe
  fmap a -> b
f (CoalgebraicExcept OptimizedStreamT (ExceptT a m) a
ae) = OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept (OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b)
-> OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b
forall a b. (a -> b) -> a -> b
$ (forall x. ExceptT a m x -> ExceptT b m x)
-> OptimizedStreamT (ExceptT a m) a
-> OptimizedStreamT (ExceptT b m) a
forall (m1 :: Type -> Type) (m2 :: Type -> Type) a.
(forall x. m1 x -> m2 x)
-> OptimizedStreamT m1 a -> OptimizedStreamT m2 a
OptimizedStreamT.hoist' ((a -> b) -> ExceptT a m x -> ExceptT b m x
forall (m :: Type -> Type) e e' a.
Functor m =>
(e -> e') -> ExceptT e m a -> ExceptT e' m a
withExceptT a -> b
f) OptimizedStreamT (ExceptT a m) a
ae

instance (Monad m) => Applicative (StreamExcept a m) where
  pure :: forall a. a -> StreamExcept a m a
pure = OptimizedStreamT (ExceptT a m) a -> StreamExcept a m a
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept (OptimizedStreamT (ExceptT a m) a -> StreamExcept a m a)
-> (a -> OptimizedStreamT (ExceptT a m) a)
-> a
-> StreamExcept a m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptT a m a -> OptimizedStreamT (ExceptT a m) a
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
constM (ExceptT a m a -> OptimizedStreamT (ExceptT a m) a)
-> (a -> ExceptT a m a) -> a -> OptimizedStreamT (ExceptT a m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ExceptT a m a
forall (m :: Type -> Type) e a. Monad m => e -> ExceptT e m a
throwE
  CoalgebraicExcept OptimizedStreamT (ExceptT (a -> b) m) a
f <*> :: forall a b.
StreamExcept a m (a -> b)
-> StreamExcept a m a -> StreamExcept a m b
<*> CoalgebraicExcept OptimizedStreamT (ExceptT a m) a
a = OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept (OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b)
-> OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b
forall a b. (a -> b) -> a -> b
$ OptimizedStreamT (ExceptT (a -> b) m) a
-> OptimizedStreamT (ExceptT a m) a
-> OptimizedStreamT (ExceptT b m) a
forall (m :: Type -> Type) e1 e2 a.
Monad m =>
OptimizedStreamT (ExceptT (e1 -> e2) m) a
-> OptimizedStreamT (ExceptT e1 m) a
-> OptimizedStreamT (ExceptT e2 m) a
applyExcept OptimizedStreamT (ExceptT (a -> b) m) a
f OptimizedStreamT (ExceptT a m) a
a
  StreamExcept a m (a -> b)
f <*> StreamExcept a m a
a = StreamExcept a m (a -> b)
-> StreamExcept a m a -> StreamExcept a m b
forall (m :: Type -> Type) a b. Monad m => m (a -> b) -> m a -> m b
ap StreamExcept a m (a -> b)
f StreamExcept a m a
a

instance (Monad m) => Selective (StreamExcept a m) where
  select :: forall a b.
StreamExcept a m (Either a b)
-> StreamExcept a m (a -> b) -> StreamExcept a m b
select (CoalgebraicExcept OptimizedStreamT (ExceptT (Either a b) m) a
e) (CoalgebraicExcept OptimizedStreamT (ExceptT (a -> b) m) a
f) = OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept (OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b)
-> OptimizedStreamT (ExceptT b m) a -> StreamExcept a m b
forall a b. (a -> b) -> a -> b
$ OptimizedStreamT (ExceptT (Either a b) m) a
-> OptimizedStreamT (ExceptT (a -> b) m) a
-> OptimizedStreamT (ExceptT b m) a
forall (m :: Type -> Type) e1 e2 a.
Monad m =>
OptimizedStreamT (ExceptT (Either e1 e2) m) a
-> OptimizedStreamT (ExceptT (e1 -> e2) m) a
-> OptimizedStreamT (ExceptT e2 m) a
selectExcept OptimizedStreamT (ExceptT (Either a b) m) a
e OptimizedStreamT (ExceptT (a -> b) m) a
f
  select StreamExcept a m (Either a b)
e StreamExcept a m (a -> b)
f = StreamExcept a m (Either a b)
-> StreamExcept a m (a -> b) -> StreamExcept a m b
forall (f :: Type -> Type) a b.
Monad f =>
f (Either a b) -> f (a -> b) -> f b
selectM StreamExcept a m (Either a b)
e StreamExcept a m (a -> b)
f

-- | 'return'/'pure' throw exceptions, '(>>=)' uses the last thrown exception as input for an exception handler.
instance (Monad m) => Monad (StreamExcept a m) where
  >> :: forall a b.
StreamExcept a m a -> StreamExcept a m b -> StreamExcept a m b
(>>) = StreamExcept a m a -> StreamExcept a m b -> StreamExcept a m b
forall a b.
StreamExcept a m a -> StreamExcept a m b -> StreamExcept a m b
forall (f :: Type -> Type) a b. Applicative f => f a -> f b -> f b
(*>)
  StreamExcept a m a
ae >>= :: forall a b.
StreamExcept a m a
-> (a -> StreamExcept a m b) -> StreamExcept a m b
>>= a -> StreamExcept a m b
f = Recursive (ExceptT b m) a -> StreamExcept a m b
forall a (m :: Type -> Type) e.
Recursive (ExceptT e m) a -> StreamExcept a m e
RecursiveExcept (Recursive (ExceptT b m) a -> StreamExcept a m b)
-> Recursive (ExceptT b m) a -> StreamExcept a m b
forall a b. (a -> b) -> a -> b
$ Recursive (ExceptT a m) a
-> (a -> Recursive (ExceptT b m) a) -> Recursive (ExceptT b m) a
forall (m :: Type -> Type) e1 b e2.
Monad m =>
Recursive (ExceptT e1 m) b
-> (e1 -> Recursive (ExceptT e2 m) b) -> Recursive (ExceptT e2 m) b
handleExceptT (StreamExcept a m a -> Recursive (ExceptT a m) a
forall (m :: Type -> Type) a e.
Functor m =>
StreamExcept a m e -> Recursive (ExceptT e m) a
toRecursive StreamExcept a m a
ae) (StreamExcept a m b -> Recursive (ExceptT b m) a
forall (m :: Type -> Type) a e.
Functor m =>
StreamExcept a m e -> Recursive (ExceptT e m) a
toRecursive (StreamExcept a m b -> Recursive (ExceptT b m) a)
-> (a -> StreamExcept a m b) -> a -> Recursive (ExceptT b m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> StreamExcept a m b
f)

instance MonadTrans (StreamExcept a) where
  lift :: forall (m :: Type -> Type) a. Monad m => m a -> StreamExcept a m a
lift = OptimizedStreamT (ExceptT a m) a -> StreamExcept a m a
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept (OptimizedStreamT (ExceptT a m) a -> StreamExcept a m a)
-> (m a -> OptimizedStreamT (ExceptT a m) a)
-> m a
-> StreamExcept a m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptT a m a -> OptimizedStreamT (ExceptT a m) a
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
constM (ExceptT a m a -> OptimizedStreamT (ExceptT a m) a)
-> (m a -> ExceptT a m a)
-> m a
-> OptimizedStreamT (ExceptT a m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (Either a a) -> ExceptT a m a
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either a a) -> ExceptT a m a)
-> (m a -> m (Either a a)) -> m a -> ExceptT a m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Either a a) -> m a -> m (Either a a)
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either a a
forall a b. a -> Either a b
Left

instance MFunctor (StreamExcept a) where
  hoist :: forall (m :: Type -> Type) (n :: Type -> Type) b.
Monad m =>
(forall a. m a -> n a) -> StreamExcept a m b -> StreamExcept a n b
hoist forall a. m a -> n a
morph (RecursiveExcept Recursive (ExceptT b m) a
recursive) = Recursive (ExceptT b n) a -> StreamExcept a n b
forall a (m :: Type -> Type) e.
Recursive (ExceptT e m) a -> StreamExcept a m e
RecursiveExcept (Recursive (ExceptT b n) a -> StreamExcept a n b)
-> Recursive (ExceptT b n) a -> StreamExcept a n b
forall a b. (a -> b) -> a -> b
$ (forall a. ExceptT b m a -> ExceptT b n a)
-> Recursive (ExceptT b m) a -> Recursive (ExceptT b n) a
forall {k} (t :: (Type -> Type) -> k -> Type) (m :: Type -> Type)
       (n :: Type -> Type) (b :: k).
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> t m b -> t n b
forall (m :: Type -> Type) (n :: Type -> Type) b.
Monad m =>
(forall a. m a -> n a) -> Recursive m b -> Recursive n b
hoist ((m (Either b a) -> n (Either b a))
-> ExceptT b m a -> ExceptT b n a
forall (m :: Type -> Type) e a (n :: Type -> Type) e' b.
(m (Either e a) -> n (Either e' b))
-> ExceptT e m a -> ExceptT e' n b
mapExceptT m (Either b a) -> n (Either b a)
forall a. m a -> n a
morph) Recursive (ExceptT b m) a
recursive
  hoist forall a. m a -> n a
morph (CoalgebraicExcept OptimizedStreamT (ExceptT b m) a
coalgebraic) = OptimizedStreamT (ExceptT b n) a -> StreamExcept a n b
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept (OptimizedStreamT (ExceptT b n) a -> StreamExcept a n b)
-> OptimizedStreamT (ExceptT b n) a -> StreamExcept a n b
forall a b. (a -> b) -> a -> b
$ (forall a. ExceptT b m a -> ExceptT b n a)
-> OptimizedStreamT (ExceptT b m) a
-> OptimizedStreamT (ExceptT b n) a
forall {k} (t :: (Type -> Type) -> k -> Type) (m :: Type -> Type)
       (n :: Type -> Type) (b :: k).
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> t m b -> t n b
forall (m :: Type -> Type) (n :: Type -> Type) b.
Monad m =>
(forall a. m a -> n a)
-> OptimizedStreamT m b -> OptimizedStreamT n b
hoist ((m (Either b a) -> n (Either b a))
-> ExceptT b m a -> ExceptT b n a
forall (m :: Type -> Type) e a (n :: Type -> Type) e' b.
(m (Either e a) -> n (Either e' b))
-> ExceptT e m a -> ExceptT e' n b
mapExceptT m (Either b a) -> n (Either b a)
forall a. m a -> n a
morph) OptimizedStreamT (ExceptT b m) a
coalgebraic

safely :: (Monad m) => StreamExcept a m Void -> OptimizedStreamT m a
safely :: forall (m :: Type -> Type) a.
Monad m =>
StreamExcept a m Void -> OptimizedStreamT m a
safely = (forall a. ExceptT Void m a -> m a)
-> OptimizedStreamT (ExceptT Void m) a -> OptimizedStreamT m a
forall {k} (t :: (Type -> Type) -> k -> Type) (m :: Type -> Type)
       (n :: Type -> Type) (b :: k).
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> t m b -> t n b
forall (m :: Type -> Type) (n :: Type -> Type) b.
Monad m =>
(forall a. m a -> n a)
-> OptimizedStreamT m b -> OptimizedStreamT n b
hoist ((Either Void a -> a) -> m (Either Void a) -> m a
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Void -> a) -> (a -> a) -> Either Void a -> a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Void -> a
forall a. Void -> a
absurd a -> a
forall a. a -> a
id) (m (Either Void a) -> m a)
-> (ExceptT Void m a -> m (Either Void a))
-> ExceptT Void m a
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptT Void m a -> m (Either Void a)
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT) (OptimizedStreamT (ExceptT Void m) a -> OptimizedStreamT m a)
-> (StreamExcept a m Void -> OptimizedStreamT (ExceptT Void m) a)
-> StreamExcept a m Void
-> OptimizedStreamT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StreamExcept a m Void -> OptimizedStreamT (ExceptT Void m) a
forall a (m :: Type -> Type) e.
StreamExcept a m e -> OptimizedStreamT (ExceptT e m) a
runStreamExcept
safe :: (Monad m) => OptimizedStreamT m a -> StreamExcept a m void
safe :: forall (m :: Type -> Type) a void.
Monad m =>
OptimizedStreamT m a -> StreamExcept a m void
safe = OptimizedStreamT (ExceptT void m) a -> StreamExcept a m void
forall a (m :: Type -> Type) e.
OptimizedStreamT (ExceptT e m) a -> StreamExcept a m e
CoalgebraicExcept (OptimizedStreamT (ExceptT void m) a -> StreamExcept a m void)
-> (OptimizedStreamT m a -> OptimizedStreamT (ExceptT void m) a)
-> OptimizedStreamT m a
-> StreamExcept a m void
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. m a -> ExceptT void m a)
-> OptimizedStreamT m a -> OptimizedStreamT (ExceptT void m) a
forall {k} (t :: (Type -> Type) -> k -> Type) (m :: Type -> Type)
       (n :: Type -> Type) (b :: k).
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> t m b -> t n b
forall (m :: Type -> Type) (n :: Type -> Type) b.
Monad m =>
(forall a. m a -> n a)
-> OptimizedStreamT m b -> OptimizedStreamT n b
hoist m a -> ExceptT void m a
forall a. m a -> ExceptT void m a
forall (m :: Type -> Type) a. Monad m => m a -> ExceptT void m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

forever :: (Monad m) => StreamExcept a m e -> OptimizedStreamT m a
forever :: forall (m :: Type -> Type) a e.
Monad m =>
StreamExcept a m e -> OptimizedStreamT m a
forever recursive :: StreamExcept a m e
recursive@(RecursiveExcept Recursive (ExceptT e m) a
_) = StreamExcept a m Void -> OptimizedStreamT m a
forall (m :: Type -> Type) a.
Monad m =>
StreamExcept a m Void -> OptimizedStreamT m a
safely StreamExcept a m Void
go
  where
    go :: StreamExcept a m Void
go = StreamExcept a m e
recursive StreamExcept a m e
-> StreamExcept a m Void -> StreamExcept a m Void
forall a b.
StreamExcept a m a -> StreamExcept a m b -> StreamExcept a m b
forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
>> StreamExcept a m Void
go
forever (CoalgebraicExcept (StreamOptimized.Stateful StreamT (ExceptT e m) a
stream)) = StreamT m a -> OptimizedStreamT m a
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
StreamOptimized.Stateful (StreamT m a -> OptimizedStreamT m a)
-> StreamT m a -> OptimizedStreamT m a
forall a b. (a -> b) -> a -> b
$ StreamT (ExceptT e m) a -> StreamT m a
forall (m :: Type -> Type) e a.
(Functor m, Monad m) =>
StreamT (ExceptT e m) a -> StreamT m a
foreverExcept StreamT (ExceptT e m) a
stream
forever (CoalgebraicExcept (StreamOptimized.Stateless ExceptT e m a
f)) = m a -> OptimizedStreamT m a
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
StreamOptimized.Stateless m a
go
  where
    go :: m a
go = ExceptT e m a -> m (Either e a)
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT ExceptT e m a
f m (Either e a) -> (Either e a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m a -> e -> m a
forall a b. a -> b -> a
const m a
go) a -> m a
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure