{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UndecidableInstances #-}

module Data.Automaton where

-- base
import Control.Applicative (Alternative (..))
import Control.Arrow
import Control.Category
import Control.Monad ((<=<))
import Control.Monad.Fix (MonadFix (mfix))
import Data.Coerce (coerce)
import Data.Function ((&))
import Data.Functor ((<&>))
import Data.Functor.Compose (Compose (..))
import Data.Maybe (fromMaybe)
import Data.Monoid (Last (..), Sum (..))
import Prelude hiding (id, (.))

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

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

-- profunctors
import Data.Profunctor (Choice (..), Profunctor (..), Strong)
import Data.Profunctor.Strong (Strong (..))
import Data.Profunctor.Traversing

-- selective
import Control.Selective (Selective)

-- simple-affine-space
import Data.VectorSpace (VectorSpace (..))

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

-- automaton
import Data.Stream (StreamT (..), fixStream)
import Data.Stream.Internal (JointState (..))
import Data.Stream.Optimized (
  OptimizedStreamT (..),
  concatS,
  stepOptimizedStream,
 )
import Data.Stream.Optimized qualified as StreamOptimized
import Data.Stream.Result

-- * Constructing automata

{- | An effectful automaton in initial encoding.

* @m@: The monad in which the automaton performs side effects.
* @a@: The type of inputs the automaton constantly consumes.
* @b@: The type of outputs the automaton constantly produces.

An effectful automaton with input @a@ is the same as an effectful stream
with the additional effect of reading an input value @a@ on every step.
This is why automata are defined here as streams.

The API of automata follows that of streams ('StreamT' and 'OptimizedStreamT') closely.
The prominent addition in automata is now that they are instances of the 'Category', 'Arrow', 'Profunctor',
and related type classes.
This allows for more ways of creating or composing them.

For example, you can sequentially and parallely compose two automata:
@
automaton1 :: Automaton m a b
automaton2 :: Automaton m b c

sequentially :: Automaton m a c
sequentially = automaton1 >>> automaton2

parallely :: Automaton m (a, b) (b, c)
parallely = automaton1 *** automaton2
@
In sequential composition, the output of the first automaton is passed as input to the second one.
In parallel composition, both automata receive input simulataneously and process it independently.

Through the 'Arrow' type class, you can use 'arr' to create an automaton from a pure function,
and more generally use the arrow syntax extension to define automata.
-}
newtype Automaton m a b = Automaton {forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton :: OptimizedStreamT (ReaderT a m) b}
  deriving newtype ((forall a b. (a -> b) -> Automaton m a a -> Automaton m a b)
-> (forall a b. a -> Automaton m a b -> Automaton m a a)
-> Functor (Automaton m a)
forall a b. a -> Automaton m a b -> Automaton m a a
forall a b. (a -> b) -> Automaton m a a -> Automaton m a 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) a a b.
Functor m =>
a -> Automaton m a b -> Automaton m a a
forall (m :: Type -> Type) a a b.
Functor m =>
(a -> b) -> Automaton m a a -> Automaton m a b
$cfmap :: forall (m :: Type -> Type) a a b.
Functor m =>
(a -> b) -> Automaton m a a -> Automaton m a b
fmap :: forall a b. (a -> b) -> Automaton m a a -> Automaton m a b
$c<$ :: forall (m :: Type -> Type) a a b.
Functor m =>
a -> Automaton m a b -> Automaton m a a
<$ :: forall a b. a -> Automaton m a b -> Automaton m a a
Functor, Functor (Automaton m a)
Functor (Automaton m a) =>
(forall a. a -> Automaton m a a)
-> (forall a b.
    Automaton m a (a -> b) -> Automaton m a a -> Automaton m a b)
-> (forall a b c.
    (a -> b -> c)
    -> Automaton m a a -> Automaton m a b -> Automaton m a c)
-> (forall a b.
    Automaton m a a -> Automaton m a b -> Automaton m a b)
-> (forall a b.
    Automaton m a a -> Automaton m a b -> Automaton m a a)
-> Applicative (Automaton m a)
forall a. a -> Automaton m a a
forall a b. Automaton m a a -> Automaton m a b -> Automaton m a a
forall a b. Automaton m a a -> Automaton m a b -> Automaton m a b
forall a b.
Automaton m a (a -> b) -> Automaton m a a -> Automaton m a b
forall a b c.
(a -> b -> c)
-> Automaton m a a -> Automaton m a b -> Automaton m a 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) a.
Applicative m =>
Functor (Automaton m a)
forall (m :: Type -> Type) a a.
Applicative m =>
a -> Automaton m a a
forall (m :: Type -> Type) a a b.
Applicative m =>
Automaton m a a -> Automaton m a b -> Automaton m a a
forall (m :: Type -> Type) a a b.
Applicative m =>
Automaton m a a -> Automaton m a b -> Automaton m a b
forall (m :: Type -> Type) a a b.
Applicative m =>
Automaton m a (a -> b) -> Automaton m a a -> Automaton m a b
forall (m :: Type -> Type) a a b c.
Applicative m =>
(a -> b -> c)
-> Automaton m a a -> Automaton m a b -> Automaton m a c
$cpure :: forall (m :: Type -> Type) a a.
Applicative m =>
a -> Automaton m a a
pure :: forall a. a -> Automaton m a a
$c<*> :: forall (m :: Type -> Type) a a b.
Applicative m =>
Automaton m a (a -> b) -> Automaton m a a -> Automaton m a b
<*> :: forall a b.
Automaton m a (a -> b) -> Automaton m a a -> Automaton m a b
$cliftA2 :: forall (m :: Type -> Type) a a b c.
Applicative m =>
(a -> b -> c)
-> Automaton m a a -> Automaton m a b -> Automaton m a c
liftA2 :: forall a b c.
(a -> b -> c)
-> Automaton m a a -> Automaton m a b -> Automaton m a c
$c*> :: forall (m :: Type -> Type) a a b.
Applicative m =>
Automaton m a a -> Automaton m a b -> Automaton m a b
*> :: forall a b. Automaton m a a -> Automaton m a b -> Automaton m a b
$c<* :: forall (m :: Type -> Type) a a b.
Applicative m =>
Automaton m a a -> Automaton m a b -> Automaton m a a
<* :: forall a b. Automaton m a a -> Automaton m a b -> Automaton m a a
Applicative, Applicative (Automaton m a)
Applicative (Automaton m a) =>
(forall a. Automaton m a a)
-> (forall a.
    Automaton m a a -> Automaton m a a -> Automaton m a a)
-> (forall a. Automaton m a a -> Automaton m a [a])
-> (forall a. Automaton m a a -> Automaton m a [a])
-> Alternative (Automaton m a)
forall a. Automaton m a a
forall a. Automaton m a a -> Automaton m a [a]
forall a. Automaton m a a -> Automaton m a a -> Automaton m a 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) a.
Alternative m =>
Applicative (Automaton m a)
forall (m :: Type -> Type) a a. Alternative m => Automaton m a a
forall (m :: Type -> Type) a a.
Alternative m =>
Automaton m a a -> Automaton m a [a]
forall (m :: Type -> Type) a a.
Alternative m =>
Automaton m a a -> Automaton m a a -> Automaton m a a
$cempty :: forall (m :: Type -> Type) a a. Alternative m => Automaton m a a
empty :: forall a. Automaton m a a
$c<|> :: forall (m :: Type -> Type) a a.
Alternative m =>
Automaton m a a -> Automaton m a a -> Automaton m a a
<|> :: forall a. Automaton m a a -> Automaton m a a -> Automaton m a a
$csome :: forall (m :: Type -> Type) a a.
Alternative m =>
Automaton m a a -> Automaton m a [a]
some :: forall a. Automaton m a a -> Automaton m a [a]
$cmany :: forall (m :: Type -> Type) a a.
Alternative m =>
Automaton m a a -> Automaton m a [a]
many :: forall a. Automaton m a a -> Automaton m a [a]
Alternative, Applicative (Automaton m a)
Applicative (Automaton m a) =>
(forall a b.
 Automaton m a (Either a b)
 -> Automaton m a (a -> b) -> Automaton m a b)
-> Selective (Automaton m a)
forall a b.
Automaton m a (Either a b)
-> Automaton m a (a -> b) -> Automaton m a b
forall (f :: Type -> Type).
Applicative f =>
(forall a b. f (Either a b) -> f (a -> b) -> f b) -> Selective f
forall (m :: Type -> Type) a.
Selective m =>
Applicative (Automaton m a)
forall (m :: Type -> Type) a a b.
Selective m =>
Automaton m a (Either a b)
-> Automaton m a (a -> b) -> Automaton m a b
$cselect :: forall (m :: Type -> Type) a a b.
Selective m =>
Automaton m a (Either a b)
-> Automaton m a (a -> b) -> Automaton m a b
select :: forall a b.
Automaton m a (Either a b)
-> Automaton m a (a -> b) -> Automaton m a b
Selective, Integer -> Automaton m a b
Automaton m a b -> Automaton m a b
Automaton m a b -> Automaton m a b -> Automaton m a b
(Automaton m a b -> Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Integer -> Automaton m a b)
-> Num (Automaton m a b)
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Integer -> Automaton m a b
forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Automaton m a b -> Automaton m a b
forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
$c+ :: forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
+ :: Automaton m a b -> Automaton m a b -> Automaton m a b
$c- :: forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
- :: Automaton m a b -> Automaton m a b -> Automaton m a b
$c* :: forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
* :: Automaton m a b -> Automaton m a b -> Automaton m a b
$cnegate :: forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Automaton m a b -> Automaton m a b
negate :: Automaton m a b -> Automaton m a b
$cabs :: forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Automaton m a b -> Automaton m a b
abs :: Automaton m a b -> Automaton m a b
$csignum :: forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Automaton m a b -> Automaton m a b
signum :: Automaton m a b -> Automaton m a b
$cfromInteger :: forall (m :: Type -> Type) a b.
(Applicative m, Num b) =>
Integer -> Automaton m a b
fromInteger :: Integer -> Automaton m a b
Num, Num (Automaton m a b)
Num (Automaton m a b) =>
(Automaton m a b -> Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Rational -> Automaton m a b)
-> Fractional (Automaton m a b)
Rational -> Automaton m a b
Automaton m a b -> Automaton m a b
Automaton m a b -> Automaton m a b -> Automaton m a b
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
forall (m :: Type -> Type) a b.
(Applicative m, Fractional b) =>
Num (Automaton m a b)
forall (m :: Type -> Type) a b.
(Applicative m, Fractional b) =>
Rational -> Automaton m a b
forall (m :: Type -> Type) a b.
(Applicative m, Fractional b) =>
Automaton m a b -> Automaton m a b
forall (m :: Type -> Type) a b.
(Applicative m, Fractional b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
$c/ :: forall (m :: Type -> Type) a b.
(Applicative m, Fractional b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
/ :: Automaton m a b -> Automaton m a b -> Automaton m a b
$crecip :: forall (m :: Type -> Type) a b.
(Applicative m, Fractional b) =>
Automaton m a b -> Automaton m a b
recip :: Automaton m a b -> Automaton m a b
$cfromRational :: forall (m :: Type -> Type) a b.
(Applicative m, Fractional b) =>
Rational -> Automaton m a b
fromRational :: Rational -> Automaton m a b
Fractional, Fractional (Automaton m a b)
Automaton m a b
Fractional (Automaton m a b) =>
Automaton m a b
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> (Automaton m a b -> Automaton m a b)
-> Floating (Automaton m a b)
Automaton m a b -> Automaton m a b
Automaton m a b -> Automaton m a b -> Automaton m a b
forall a.
Fractional a =>
a
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> Floating a
forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Fractional (Automaton m a b)
forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b
forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
$cpi :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b
pi :: Automaton m a b
$cexp :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
exp :: Automaton m a b -> Automaton m a b
$clog :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
log :: Automaton m a b -> Automaton m a b
$csqrt :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
sqrt :: Automaton m a b -> Automaton m a b
$c** :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
** :: Automaton m a b -> Automaton m a b -> Automaton m a b
$clogBase :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b -> Automaton m a b
logBase :: Automaton m a b -> Automaton m a b -> Automaton m a b
$csin :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
sin :: Automaton m a b -> Automaton m a b
$ccos :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
cos :: Automaton m a b -> Automaton m a b
$ctan :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
tan :: Automaton m a b -> Automaton m a b
$casin :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
asin :: Automaton m a b -> Automaton m a b
$cacos :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
acos :: Automaton m a b -> Automaton m a b
$catan :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
atan :: Automaton m a b -> Automaton m a b
$csinh :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
sinh :: Automaton m a b -> Automaton m a b
$ccosh :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
cosh :: Automaton m a b -> Automaton m a b
$ctanh :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
tanh :: Automaton m a b -> Automaton m a b
$casinh :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
asinh :: Automaton m a b -> Automaton m a b
$cacosh :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
acosh :: Automaton m a b -> Automaton m a b
$catanh :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
atanh :: Automaton m a b -> Automaton m a b
$clog1p :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
log1p :: Automaton m a b -> Automaton m a b
$cexpm1 :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
expm1 :: Automaton m a b -> Automaton m a b
$clog1pexp :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
log1pexp :: Automaton m a b -> Automaton m a b
$clog1mexp :: forall (m :: Type -> Type) a b.
(Applicative m, Floating b) =>
Automaton m a b -> Automaton m a b
log1mexp :: Automaton m a b -> Automaton m a b
Floating)

-- | Create an 'Automaton' from a state and a pure step function.
unfold ::
  (Applicative m) =>
  -- | The initial state
  s ->
  -- | The step function
  (a -> s -> Result s b) ->
  Automaton m a b
unfold :: forall (m :: Type -> Type) s a b.
Applicative m =>
s -> (a -> s -> Result s b) -> Automaton m a b
unfold s
state a -> s -> Result s b
step = s -> (a -> s -> m (Result s b)) -> Automaton m a b
forall s a (m :: Type -> Type) b.
s -> (a -> s -> m (Result s b)) -> Automaton m a b
unfoldM s
state ((a -> s -> m (Result s b)) -> Automaton m a b)
-> (a -> s -> m (Result s b)) -> Automaton m a b
forall a b. (a -> b) -> a -> b
$ (Result s b -> m (Result s b))
-> (s -> Result s b) -> s -> m (Result s b)
forall a b. (a -> b) -> (s -> a) -> s -> b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Result s b -> m (Result s b)
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ((s -> Result s b) -> s -> m (Result s b))
-> (a -> s -> Result s b) -> a -> s -> m (Result s b)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> s -> Result s b
step

-- | Create an 'Automaton' from a state and an effectful step function.
unfoldM ::
  -- | The initial state
  s ->
  -- | The step function
  (a -> s -> m (Result s b)) ->
  Automaton m a b
unfoldM :: forall s a (m :: Type -> Type) b.
s -> (a -> s -> m (Result s b)) -> Automaton m a b
unfoldM s
state a -> s -> m (Result s b)
step = OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) b -> Automaton m a b)
-> OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall a b. (a -> b) -> a -> b
$! StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b)
-> StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b
forall a b. (a -> b) -> a -> b
$! StreamT {s
state :: s
state :: s
state, step :: s -> ReaderT a m (Result s b)
step = \s
s -> (a -> m (Result s b)) -> ReaderT a m (Result s b)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((a -> m (Result s b)) -> ReaderT a m (Result s b))
-> (a -> m (Result s b)) -> ReaderT a m (Result s b)
forall a b. (a -> b) -> a -> b
$ \a
a -> a -> s -> m (Result s b)
step a
a s
s}

instance (Eq s, Floating s, VectorSpace v s, Applicative m) => VectorSpace (Automaton m a v) (Automaton m a s) where
  zeroVector :: Automaton m a v
zeroVector = OptimizedStreamT (ReaderT a m) v -> Automaton m a v
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton OptimizedStreamT (ReaderT a m) v
forall v a. VectorSpace v a => v
zeroVector
  Automaton OptimizedStreamT (ReaderT a m) s
s *^ :: Automaton m a s -> Automaton m a v -> Automaton m a v
*^ Automaton OptimizedStreamT (ReaderT a m) v
v = OptimizedStreamT (ReaderT a m) v -> Automaton m a v
forall a b. Coercible a b => a -> b
coerce (OptimizedStreamT (ReaderT a m) v -> Automaton m a v)
-> OptimizedStreamT (ReaderT a m) v -> Automaton m a v
forall a b. (a -> b) -> a -> b
$ OptimizedStreamT (ReaderT a m) s
s OptimizedStreamT (ReaderT a m) s
-> OptimizedStreamT (ReaderT a m) v
-> OptimizedStreamT (ReaderT a m) v
forall v a. VectorSpace v a => a -> v -> v
*^ OptimizedStreamT (ReaderT a m) v
v
  Automaton OptimizedStreamT (ReaderT a m) v
v1 ^+^ :: Automaton m a v -> Automaton m a v -> Automaton m a v
^+^ Automaton OptimizedStreamT (ReaderT a m) v
v2 = OptimizedStreamT (ReaderT a m) v -> Automaton m a v
forall a b. Coercible a b => a -> b
coerce (OptimizedStreamT (ReaderT a m) v -> Automaton m a v)
-> OptimizedStreamT (ReaderT a m) v -> Automaton m a v
forall a b. (a -> b) -> a -> b
$ OptimizedStreamT (ReaderT a m) v
v1 OptimizedStreamT (ReaderT a m) v
-> OptimizedStreamT (ReaderT a m) v
-> OptimizedStreamT (ReaderT a m) v
forall v a. VectorSpace v a => v -> v -> v
^+^ OptimizedStreamT (ReaderT a m) v
v2
  dot :: Automaton m a v -> Automaton m a v -> Automaton m a s
dot (Automaton OptimizedStreamT (ReaderT a m) v
s) (Automaton OptimizedStreamT (ReaderT a m) v
v) = OptimizedStreamT (ReaderT a m) s -> Automaton m a s
forall a b. Coercible a b => a -> b
coerce (OptimizedStreamT (ReaderT a m) s -> Automaton m a s)
-> OptimizedStreamT (ReaderT a m) s -> Automaton m a s
forall a b. (a -> b) -> a -> b
$ OptimizedStreamT (ReaderT a m) v
-> OptimizedStreamT (ReaderT a m) v
-> OptimizedStreamT (ReaderT a m) s
forall v a. VectorSpace v a => v -> v -> a
dot OptimizedStreamT (ReaderT a m) v
s OptimizedStreamT (ReaderT a m) v
v
  normalize :: Automaton m a v -> Automaton m a v
normalize (Automaton OptimizedStreamT (ReaderT a m) v
v) = OptimizedStreamT (ReaderT a m) v -> Automaton m a v
forall a b. Coercible a b => a -> b
coerce OptimizedStreamT (ReaderT a m) v
v

instance (Semialign m) => Semialign (Automaton m a) where
  align :: forall a b.
Automaton m a a -> Automaton m a b -> Automaton m a (These a b)
align Automaton m a a
automaton1 Automaton m a b
automaton2 =
    OptimizedStreamT (ReaderT a m) (These a b)
-> Automaton m a (These a b)
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) (These a b)
 -> Automaton m a (These a b))
-> OptimizedStreamT (ReaderT a m) (These a b)
-> Automaton m a (These a b)
forall a b. (a -> b) -> a -> b
$
      (forall x. Compose ((->) a) m x -> ReaderT a m x)
-> OptimizedStreamT (Compose ((->) a) m) (These a b)
-> OptimizedStreamT (ReaderT a m) (These a b)
forall (m1 :: Type -> Type) (m2 :: Type -> Type) a.
(forall x. m1 x -> m2 x)
-> OptimizedStreamT m1 a -> OptimizedStreamT m2 a
StreamOptimized.hoist' ((a -> m x) -> ReaderT a m x
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((a -> m x) -> ReaderT a m x)
-> (Compose ((->) a) m x -> a -> m x)
-> Compose ((->) a) m x
-> ReaderT a m x
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
. Compose ((->) a) m x -> a -> m x
forall {k1} {k2} (f :: k1 -> Type) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose) (OptimizedStreamT (Compose ((->) a) m) (These a b)
 -> OptimizedStreamT (ReaderT a m) (These a b))
-> OptimizedStreamT (Compose ((->) a) m) (These a b)
-> OptimizedStreamT (ReaderT a m) (These a b)
forall a b. (a -> b) -> a -> b
$
        OptimizedStreamT (Compose ((->) a) m) a
-> OptimizedStreamT (Compose ((->) a) m) b
-> OptimizedStreamT (Compose ((->) a) m) (These a b)
forall a b.
OptimizedStreamT (Compose ((->) a) m) a
-> OptimizedStreamT (Compose ((->) a) m) b
-> OptimizedStreamT (Compose ((->) a) m) (These a b)
forall (f :: Type -> Type) a b.
Semialign f =>
f a -> f b -> f (These a b)
align
          ((forall x. ReaderT a m x -> Compose ((->) a) m x)
-> OptimizedStreamT (ReaderT a m) a
-> OptimizedStreamT (Compose ((->) a) m) a
forall (m1 :: Type -> Type) (m2 :: Type -> Type) a.
(forall x. m1 x -> m2 x)
-> OptimizedStreamT m1 a -> OptimizedStreamT m2 a
StreamOptimized.hoist' ((a -> m x) -> Compose ((->) a) m x
forall {k} {k1} (f :: k -> Type) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose ((a -> m x) -> Compose ((->) a) m x)
-> (ReaderT a m x -> a -> m x)
-> ReaderT a m x
-> Compose ((->) a) m x
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
. ReaderT a m x -> a -> m x
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT) (OptimizedStreamT (ReaderT a m) a
 -> OptimizedStreamT (Compose ((->) a) m) a)
-> OptimizedStreamT (ReaderT a m) a
-> OptimizedStreamT (Compose ((->) a) m) a
forall a b. (a -> b) -> a -> b
$ Automaton m a a -> OptimizedStreamT (ReaderT a m) a
forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton Automaton m a a
automaton1)
          ((forall x. ReaderT a m x -> Compose ((->) a) m x)
-> OptimizedStreamT (ReaderT a m) b
-> OptimizedStreamT (Compose ((->) a) m) b
forall (m1 :: Type -> Type) (m2 :: Type -> Type) a.
(forall x. m1 x -> m2 x)
-> OptimizedStreamT m1 a -> OptimizedStreamT m2 a
StreamOptimized.hoist' ((a -> m x) -> Compose ((->) a) m x
forall {k} {k1} (f :: k -> Type) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose ((a -> m x) -> Compose ((->) a) m x)
-> (ReaderT a m x -> a -> m x)
-> ReaderT a m x
-> Compose ((->) a) m x
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
. ReaderT a m x -> a -> m x
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT) (OptimizedStreamT (ReaderT a m) b
 -> OptimizedStreamT (Compose ((->) a) m) b)
-> OptimizedStreamT (ReaderT a m) b
-> OptimizedStreamT (Compose ((->) a) m) b
forall a b. (a -> b) -> a -> b
$ Automaton m a b -> OptimizedStreamT (ReaderT a m) b
forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton Automaton m a b
automaton2)

instance (Align m) => Align (Automaton m a) where
  nil :: forall a. Automaton m a a
nil = m a -> Automaton m a a
forall (m :: Type -> Type) b a. Functor m => m b -> Automaton m a b
constM m a
forall a. m a
forall (f :: Type -> Type) a. Align f => f a
nil

instance (Monad m) => Category (Automaton m) where
  id :: forall a. Automaton m a a
id = OptimizedStreamT (ReaderT a m) a -> Automaton m a a
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) a -> Automaton m a a)
-> OptimizedStreamT (ReaderT a m) a -> Automaton m a a
forall a b. (a -> b) -> a -> b
$ ReaderT a m a -> OptimizedStreamT (ReaderT a m) a
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless ReaderT a m a
forall (m :: Type -> Type) r. Monad m => ReaderT r m r
ask
  {-# INLINE id #-}

  Automaton (Stateful (StreamT s
stateF0 s -> ReaderT b m (Result s c)
stepF)) . :: forall b c a. Automaton m b c -> Automaton m a b -> Automaton m a c
. Automaton (Stateful (StreamT s
stateG0 s -> ReaderT a m (Result s b)
stepG)) =
    OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) c -> Automaton m a c)
-> OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c)
-> StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { state :: JointState s s
state = s -> s -> JointState s s
forall a b. a -> b -> JointState a b
JointState s
stateF0 s
stateG0
          , step :: JointState s s -> ReaderT a m (Result (JointState s s) c)
step = \(JointState s
stateF s
stateG) -> do
              Result s
stateG' b
b <- s -> ReaderT a m (Result s b)
stepG s
stateG
              Result s
stateF' c
c <- m (Result s c) -> ReaderT a m (Result s c)
forall (m :: Type -> Type) a. Monad m => m a -> ReaderT a m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Result s c) -> ReaderT a m (Result s c))
-> m (Result s c) -> ReaderT a m (Result s c)
forall a b. (a -> b) -> a -> b
$! ReaderT b m (Result s c) -> b -> m (Result s c)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT b m (Result s c)
stepF s
stateF) b
b
              Result (JointState s s) c
-> ReaderT a m (Result (JointState s s) c)
forall a. a -> ReaderT a m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Result (JointState s s) c
 -> ReaderT a m (Result (JointState s s) c))
-> Result (JointState s s) c
-> ReaderT a m (Result (JointState s s) c)
forall a b. (a -> b) -> a -> b
$! JointState s s -> c -> Result (JointState s s) c
forall s a. s -> a -> Result s a
Result (s -> s -> JointState s s
forall a b. a -> b -> JointState a b
JointState s
stateF' s
stateG') c
c
          }
  Automaton (Stateful (StreamT s
state0 s -> ReaderT b m (Result s c)
step)) . Automaton (Stateless ReaderT a m b
m) =
    OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) c -> Automaton m a c)
-> OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c)
-> StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { state :: s
state = s
state0
          , step :: s -> ReaderT a m (Result s c)
step = \s
state -> do
              b
b <- ReaderT a m b
m
              m (Result s c) -> ReaderT a m (Result s c)
forall (m :: Type -> Type) a. Monad m => m a -> ReaderT a m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Result s c) -> ReaderT a m (Result s c))
-> m (Result s c) -> ReaderT a m (Result s c)
forall a b. (a -> b) -> a -> b
$! ReaderT b m (Result s c) -> b -> m (Result s c)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT b m (Result s c)
step s
state) b
b
          }
  Automaton (Stateless ReaderT b m c
m) . Automaton (Stateful (StreamT s
state0 s -> ReaderT a m (Result s b)
step)) =
    OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) c -> Automaton m a c)
-> OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c)
-> StreamT (ReaderT a m) c -> OptimizedStreamT (ReaderT a m) c
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { state :: s
state = s
state0
          , step :: s -> ReaderT a m (Result s c)
step = \s
state -> do
              Result s
state' b
b <- s -> ReaderT a m (Result s b)
step s
state
              c
c <- m c -> ReaderT a m c
forall (m :: Type -> Type) a. Monad m => m a -> ReaderT a m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m c -> ReaderT a m c) -> m c -> ReaderT a m c
forall a b. (a -> b) -> a -> b
$! ReaderT b m c -> b -> m c
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT b m c
m b
b
              Result s c -> ReaderT a m (Result s c)
forall a. a -> ReaderT a m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Result s c -> ReaderT a m (Result s c))
-> Result s c -> ReaderT a m (Result s c)
forall a b. (a -> b) -> a -> b
$! s -> c -> Result s c
forall s a. s -> a -> Result s a
Result s
state' c
c
          }
  Automaton (Stateless ReaderT b m c
f) . Automaton (Stateless ReaderT a m b
g) = OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) c -> Automaton m a c)
-> OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall a b. (a -> b) -> a -> b
$ ReaderT a m c -> OptimizedStreamT (ReaderT a m) c
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT a m c -> OptimizedStreamT (ReaderT a m) c)
-> ReaderT a m c -> OptimizedStreamT (ReaderT a m) c
forall a b. (a -> b) -> a -> b
$ (a -> m c) -> ReaderT a m c
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((a -> m c) -> ReaderT a m c) -> (a -> m c) -> ReaderT a m c
forall a b. (a -> b) -> a -> b
$ ReaderT b m c -> b -> m c
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT b m c
f (b -> m c) -> (a -> m b) -> a -> m c
forall (m :: Type -> Type) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ReaderT a m b -> a -> m b
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT a m b
g
  {-# INLINE (.) #-}

instance (Monad m) => Arrow (Automaton m) where
  arr :: forall b c. (b -> c) -> Automaton m b c
arr b -> c
f = OptimizedStreamT (ReaderT b m) c -> Automaton m b c
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT b m) c -> Automaton m b c)
-> OptimizedStreamT (ReaderT b m) c -> Automaton m b c
forall a b. (a -> b) -> a -> b
$! ReaderT b m c -> OptimizedStreamT (ReaderT b m) c
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT b m c -> OptimizedStreamT (ReaderT b m) c)
-> ReaderT b m c -> OptimizedStreamT (ReaderT b m) c
forall a b. (a -> b) -> a -> b
$! (b -> c) -> ReaderT b m c
forall (m :: Type -> Type) r a.
Monad m =>
(r -> a) -> ReaderT r m a
asks b -> c
f
  {-# INLINE arr #-}

  first :: forall b c d. Automaton m b c -> Automaton m (b, d) (c, d)
first (Automaton (Stateful StreamT {s
state :: ()
state :: s
state, s -> ReaderT b m (Result s c)
step :: ()
step :: s -> ReaderT b m (Result s c)
step})) =
    OptimizedStreamT (ReaderT (b, d) m) (c, d)
-> Automaton m (b, d) (c, d)
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (b, d) m) (c, d)
 -> Automaton m (b, d) (c, d))
-> OptimizedStreamT (ReaderT (b, d) m) (c, d)
-> Automaton m (b, d) (c, d)
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT (b, d) m) (c, d)
-> OptimizedStreamT (ReaderT (b, d) m) (c, d)
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT (b, d) m) (c, d)
 -> OptimizedStreamT (ReaderT (b, d) m) (c, d))
-> StreamT (ReaderT (b, d) m) (c, d)
-> OptimizedStreamT (ReaderT (b, d) m) (c, d)
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { s
state :: s
state :: s
state
          , step :: s -> ReaderT (b, d) m (Result s (c, d))
step = \s
s ->
              ((b, d) -> m (Result s (c, d)))
-> ReaderT (b, d) m (Result s (c, d))
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT
                ( \(b
b, d
d) ->
                    (c -> (c, d)) -> Result s c -> Result s (c, d)
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (,d
d)
                      (Result s c -> Result s (c, d))
-> m (Result s c) -> m (Result s (c, d))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT b m (Result s c) -> b -> m (Result s c)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT b m (Result s c)
step s
s) b
b
                )
          }
  first (Automaton (Stateless ReaderT b m c
m)) = OptimizedStreamT (ReaderT (b, d) m) (c, d)
-> Automaton m (b, d) (c, d)
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (b, d) m) (c, d)
 -> Automaton m (b, d) (c, d))
-> OptimizedStreamT (ReaderT (b, d) m) (c, d)
-> Automaton m (b, d) (c, d)
forall a b. (a -> b) -> a -> b
$ ReaderT (b, d) m (c, d)
-> OptimizedStreamT (ReaderT (b, d) m) (c, d)
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT (b, d) m (c, d)
 -> OptimizedStreamT (ReaderT (b, d) m) (c, d))
-> ReaderT (b, d) m (c, d)
-> OptimizedStreamT (ReaderT (b, d) m) (c, d)
forall a b. (a -> b) -> a -> b
$ ((b, d) -> m (c, d)) -> ReaderT (b, d) m (c, d)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT (((b, d) -> m (c, d)) -> ReaderT (b, d) m (c, d))
-> ((b, d) -> m (c, d)) -> ReaderT (b, d) m (c, d)
forall a b. (a -> b) -> a -> b
$ \(b
b, d
d) -> (,d
d) (c -> (c, d)) -> m c -> m (c, d)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT b m c -> b -> m c
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT b m c
m b
b
  {-# INLINE first #-}

instance (Monad m) => ArrowChoice (Automaton m) where
  Automaton (Stateful (StreamT s
stateL0 s -> ReaderT b m (Result s c)
stepL)) +++ :: forall b c b' c'.
Automaton m b c
-> Automaton m b' c' -> Automaton m (Either b b') (Either c c')
+++ Automaton (Stateful (StreamT s
stateR0 s -> ReaderT b' m (Result s c')
stepR)) =
    OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
-> Automaton m (Either b b') (Either c c')
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
 -> Automaton m (Either b b') (Either c c'))
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
-> Automaton m (Either b b') (Either c c')
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT (Either b b') m) (Either c c')
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT (Either b b') m) (Either c c')
 -> OptimizedStreamT (ReaderT (Either b b') m) (Either c c'))
-> StreamT (ReaderT (Either b b') m) (Either c c')
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { state :: JointState s s
state = s -> s -> JointState s s
forall a b. a -> b -> JointState a b
JointState s
stateL0 s
stateR0
          , step :: JointState s s
-> ReaderT (Either b b') m (Result (JointState s s) (Either c c'))
step = \(JointState s
stateL s
stateR) ->
              (Either b b' -> m (Result (JointState s s) (Either c c')))
-> ReaderT (Either b b') m (Result (JointState s s) (Either c c'))
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((Either b b' -> m (Result (JointState s s) (Either c c')))
 -> ReaderT (Either b b') m (Result (JointState s s) (Either c c')))
-> (Either b b' -> m (Result (JointState s s) (Either c c')))
-> ReaderT (Either b b') m (Result (JointState s s) (Either c c'))
forall a b. (a -> b) -> a -> b
$!
                (b -> m (Result (JointState s s) (Either c c')))
-> (b' -> m (Result (JointState s s) (Either c c')))
-> Either b b'
-> m (Result (JointState s s) (Either c c'))
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
                  (ReaderT b m (Result (JointState s s) (Either c c'))
-> b -> m (Result (JointState s s) (Either c c'))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ((s -> JointState s s)
-> Result s (Either c c') -> Result (JointState s s) (Either c c')
forall s1 s2 a. (s1 -> s2) -> Result s1 a -> Result s2 a
mapResultState (s -> s -> JointState s s
forall a b. a -> b -> JointState a b
`JointState` s
stateR) (Result s (Either c c') -> Result (JointState s s) (Either c c'))
-> (Result s c -> Result s (Either c c'))
-> Result s c
-> Result (JointState s s) (Either c c')
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
. (c -> Either c c') -> Result s c -> Result s (Either c c')
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> Either c c'
forall a b. a -> Either a b
Left (Result s c -> Result (JointState s s) (Either c c'))
-> ReaderT b m (Result s c)
-> ReaderT b m (Result (JointState s s) (Either c c'))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> ReaderT b m (Result s c)
stepL s
stateL))
                  (ReaderT b' m (Result (JointState s s) (Either c c'))
-> b' -> m (Result (JointState s s) (Either c c'))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ((s -> JointState s s)
-> Result s (Either c c') -> Result (JointState s s) (Either c c')
forall s1 s2 a. (s1 -> s2) -> Result s1 a -> Result s2 a
mapResultState (s -> s -> JointState s s
forall a b. a -> b -> JointState a b
JointState s
stateL) (Result s (Either c c') -> Result (JointState s s) (Either c c'))
-> (Result s c' -> Result s (Either c c'))
-> Result s c'
-> Result (JointState s s) (Either c c')
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
. (c' -> Either c c') -> Result s c' -> Result s (Either c c')
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c' -> Either c c'
forall a b. b -> Either a b
Right (Result s c' -> Result (JointState s s) (Either c c'))
-> ReaderT b' m (Result s c')
-> ReaderT b' m (Result (JointState s s) (Either c c'))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> ReaderT b' m (Result s c')
stepR s
stateR))
          }
  Automaton (Stateless ReaderT b m c
m) +++ Automaton (Stateful (StreamT s
state0 s -> ReaderT b' m (Result s c')
step)) =
    OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
-> Automaton m (Either b b') (Either c c')
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
 -> Automaton m (Either b b') (Either c c'))
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
-> Automaton m (Either b b') (Either c c')
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT (Either b b') m) (Either c c')
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT (Either b b') m) (Either c c')
 -> OptimizedStreamT (ReaderT (Either b b') m) (Either c c'))
-> StreamT (ReaderT (Either b b') m) (Either c c')
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { state :: s
state = s
state0
          , step :: s -> ReaderT (Either b b') m (Result s (Either c c'))
step = \s
state ->
              (Either b b' -> m (Result s (Either c c')))
-> ReaderT (Either b b') m (Result s (Either c c'))
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((Either b b' -> m (Result s (Either c c')))
 -> ReaderT (Either b b') m (Result s (Either c c')))
-> (Either b b' -> m (Result s (Either c c')))
-> ReaderT (Either b b') m (Result s (Either c c'))
forall a b. (a -> b) -> a -> b
$!
                (b -> m (Result s (Either c c')))
-> (b' -> m (Result s (Either c c')))
-> Either b b'
-> m (Result s (Either c c'))
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
                  (ReaderT b m (Result s (Either c c'))
-> b -> m (Result s (Either c c'))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT b m (Result s (Either c c'))
 -> b -> m (Result s (Either c c')))
-> (ReaderT b m c -> ReaderT b m (Result s (Either c c')))
-> ReaderT b m c
-> b
-> m (Result s (Either c c'))
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
. (c -> Result s (Either c c'))
-> ReaderT b m c -> ReaderT b m (Result s (Either c c'))
forall a b. (a -> b) -> ReaderT b m a -> ReaderT b m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (s -> Either c c' -> Result s (Either c c')
forall s a. s -> a -> Result s a
Result s
state (Either c c' -> Result s (Either c c'))
-> (c -> Either c c') -> c -> Result s (Either c c')
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
. c -> Either c c'
forall a b. a -> Either a b
Left) (ReaderT b m c -> b -> m (Result s (Either c c')))
-> ReaderT b m c -> b -> m (Result s (Either c c'))
forall a b. (a -> b) -> a -> b
$ ReaderT b m c
m)
                  (ReaderT b' m (Result s (Either c c'))
-> b' -> m (Result s (Either c c'))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT b' m (Result s (Either c c'))
 -> b' -> m (Result s (Either c c')))
-> (ReaderT b' m (Result s c')
    -> ReaderT b' m (Result s (Either c c')))
-> ReaderT b' m (Result s c')
-> b'
-> m (Result s (Either c c'))
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
. (Result s c' -> Result s (Either c c'))
-> ReaderT b' m (Result s c')
-> ReaderT b' m (Result s (Either c c'))
forall a b. (a -> b) -> ReaderT b' m a -> ReaderT b' m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((c' -> Either c c') -> Result s c' -> Result s (Either c c')
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c' -> Either c c'
forall a b. b -> Either a b
Right) (ReaderT b' m (Result s c') -> b' -> m (Result s (Either c c')))
-> ReaderT b' m (Result s c') -> b' -> m (Result s (Either c c'))
forall a b. (a -> b) -> a -> b
$ s -> ReaderT b' m (Result s c')
step s
state)
          }
  Automaton (Stateful (StreamT s
state0 s -> ReaderT b m (Result s c)
step)) +++ Automaton (Stateless ReaderT b' m c'
m) =
    OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
-> Automaton m (Either b b') (Either c c')
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
 -> Automaton m (Either b b') (Either c c'))
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
-> Automaton m (Either b b') (Either c c')
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT (Either b b') m) (Either c c')
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT (Either b b') m) (Either c c')
 -> OptimizedStreamT (ReaderT (Either b b') m) (Either c c'))
-> StreamT (ReaderT (Either b b') m) (Either c c')
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { state :: s
state = s
state0
          , step :: s -> ReaderT (Either b b') m (Result s (Either c c'))
step = \s
state ->
              (Either b b' -> m (Result s (Either c c')))
-> ReaderT (Either b b') m (Result s (Either c c'))
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((Either b b' -> m (Result s (Either c c')))
 -> ReaderT (Either b b') m (Result s (Either c c')))
-> (Either b b' -> m (Result s (Either c c')))
-> ReaderT (Either b b') m (Result s (Either c c'))
forall a b. (a -> b) -> a -> b
$!
                (b -> m (Result s (Either c c')))
-> (b' -> m (Result s (Either c c')))
-> Either b b'
-> m (Result s (Either c c'))
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
                  (ReaderT b m (Result s (Either c c'))
-> b -> m (Result s (Either c c'))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT b m (Result s (Either c c'))
 -> b -> m (Result s (Either c c')))
-> (ReaderT b m (Result s c)
    -> ReaderT b m (Result s (Either c c')))
-> ReaderT b m (Result s c)
-> b
-> m (Result s (Either c c'))
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
. (Result s c -> Result s (Either c c'))
-> ReaderT b m (Result s c) -> ReaderT b m (Result s (Either c c'))
forall a b. (a -> b) -> ReaderT b m a -> ReaderT b m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((c -> Either c c') -> Result s c -> Result s (Either c c')
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> Either c c'
forall a b. a -> Either a b
Left) (ReaderT b m (Result s c) -> b -> m (Result s (Either c c')))
-> ReaderT b m (Result s c) -> b -> m (Result s (Either c c'))
forall a b. (a -> b) -> a -> b
$ s -> ReaderT b m (Result s c)
step s
state)
                  (ReaderT b' m (Result s (Either c c'))
-> b' -> m (Result s (Either c c'))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT b' m (Result s (Either c c'))
 -> b' -> m (Result s (Either c c')))
-> (ReaderT b' m c' -> ReaderT b' m (Result s (Either c c')))
-> ReaderT b' m c'
-> b'
-> m (Result s (Either c c'))
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
. (c' -> Result s (Either c c'))
-> ReaderT b' m c' -> ReaderT b' m (Result s (Either c c'))
forall a b. (a -> b) -> ReaderT b' m a -> ReaderT b' m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (s -> Either c c' -> Result s (Either c c')
forall s a. s -> a -> Result s a
Result s
state (Either c c' -> Result s (Either c c'))
-> (c' -> Either c c') -> c' -> Result s (Either c c')
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
. c' -> Either c c'
forall a b. b -> Either a b
Right) (ReaderT b' m c' -> b' -> m (Result s (Either c c')))
-> ReaderT b' m c' -> b' -> m (Result s (Either c c'))
forall a b. (a -> b) -> a -> b
$ ReaderT b' m c'
m)
          }
  Automaton (Stateless ReaderT b m c
mL) +++ Automaton (Stateless ReaderT b' m c'
mR) =
    OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
-> Automaton m (Either b b') (Either c c')
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
 -> Automaton m (Either b b') (Either c c'))
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
-> Automaton m (Either b b') (Either c c')
forall a b. (a -> b) -> a -> b
$
      ReaderT (Either b b') m (Either c c')
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT (Either b b') m (Either c c')
 -> OptimizedStreamT (ReaderT (Either b b') m) (Either c c'))
-> ReaderT (Either b b') m (Either c c')
-> OptimizedStreamT (ReaderT (Either b b') m) (Either c c')
forall a b. (a -> b) -> a -> b
$
        (Either b b' -> m (Either c c'))
-> ReaderT (Either b b') m (Either c c')
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((Either b b' -> m (Either c c'))
 -> ReaderT (Either b b') m (Either c c'))
-> (Either b b' -> m (Either c c'))
-> ReaderT (Either b b') m (Either c c')
forall a b. (a -> b) -> a -> b
$
          (b -> m (Either c c'))
-> (b' -> m (Either c c')) -> Either b b' -> m (Either c c')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
            (ReaderT b m (Either c c') -> b -> m (Either c c')
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT b m (Either c c') -> b -> m (Either c c'))
-> (ReaderT b m c -> ReaderT b m (Either c c'))
-> ReaderT b m c
-> b
-> m (Either c c')
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
. (c -> Either c c') -> ReaderT b m c -> ReaderT b m (Either c c')
forall a b. (a -> b) -> ReaderT b m a -> ReaderT b m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> Either c c'
forall a b. a -> Either a b
Left (ReaderT b m c -> b -> m (Either c c'))
-> ReaderT b m c -> b -> m (Either c c')
forall a b. (a -> b) -> a -> b
$ ReaderT b m c
mL)
            (ReaderT b' m (Either c c') -> b' -> m (Either c c')
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT b' m (Either c c') -> b' -> m (Either c c'))
-> (ReaderT b' m c' -> ReaderT b' m (Either c c'))
-> ReaderT b' m c'
-> b'
-> m (Either c c')
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
. (c' -> Either c c')
-> ReaderT b' m c' -> ReaderT b' m (Either c c')
forall a b. (a -> b) -> ReaderT b' m a -> ReaderT b' m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c' -> Either c c'
forall a b. b -> Either a b
Right (ReaderT b' m c' -> b' -> m (Either c c'))
-> ReaderT b' m c' -> b' -> m (Either c c')
forall a b. (a -> b) -> a -> b
$ ReaderT b' m c'
mR)
  {-# INLINE (+++) #-}

  left :: forall b c d.
Automaton m b c -> Automaton m (Either b d) (Either c d)
left (Automaton (Stateful (StreamT {s
state :: ()
state :: s
state, s -> ReaderT b m (Result s c)
step :: ()
step :: s -> ReaderT b m (Result s c)
step}))) =
    OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
-> Automaton m (Either b d) (Either c d)
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
 -> Automaton m (Either b d) (Either c d))
-> OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
-> Automaton m (Either b d) (Either c d)
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT (Either b d) m) (Either c d)
-> OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT (Either b d) m) (Either c d)
 -> OptimizedStreamT (ReaderT (Either b d) m) (Either c d))
-> StreamT (ReaderT (Either b d) m) (Either c d)
-> OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { s
state :: s
state :: s
state
          , step :: s -> ReaderT (Either b d) m (Result s (Either c d))
step = \s
s -> (Either b d -> m (Result s (Either c d)))
-> ReaderT (Either b d) m (Result s (Either c d))
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((Either b d -> m (Result s (Either c d)))
 -> ReaderT (Either b d) m (Result s (Either c d)))
-> (Either b d -> m (Result s (Either c d)))
-> ReaderT (Either b d) m (Result s (Either c d))
forall a b. (a -> b) -> a -> b
$ (b -> m (Result s (Either c d)))
-> (d -> m (Result s (Either c d)))
-> Either b d
-> m (Result s (Either c d))
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((Result s c -> Result s (Either c d))
-> m (Result s c) -> m (Result s (Either c d))
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((c -> Either c d) -> Result s c -> Result s (Either c d)
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> Either c d
forall a b. a -> Either a b
Left) (m (Result s c) -> m (Result s (Either c d)))
-> (b -> m (Result s c)) -> b -> m (Result s (Either c d))
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
. ReaderT b m (Result s c) -> b -> m (Result s c)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT b m (Result s c)
step s
s)) (Result s (Either c d) -> m (Result s (Either c d))
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Result s (Either c d) -> m (Result s (Either c d)))
-> (d -> Result s (Either c d)) -> d -> m (Result s (Either c d))
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 -> Either c d -> Result s (Either c d)
forall s a. s -> a -> Result s a
Result s
s (Either c d -> Result s (Either c d))
-> (d -> Either c d) -> d -> Result s (Either c d)
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
. d -> Either c d
forall a b. b -> Either a b
Right)
          }
  left (Automaton (Stateless ReaderT b m c
ma)) = OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
-> Automaton m (Either b d) (Either c d)
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
 -> Automaton m (Either b d) (Either c d))
-> OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
-> Automaton m (Either b d) (Either c d)
forall a b. (a -> b) -> a -> b
$! ReaderT (Either b d) m (Either c d)
-> OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT (Either b d) m (Either c d)
 -> OptimizedStreamT (ReaderT (Either b d) m) (Either c d))
-> ReaderT (Either b d) m (Either c d)
-> OptimizedStreamT (ReaderT (Either b d) m) (Either c d)
forall a b. (a -> b) -> a -> b
$! (Either b d -> m (Either c d))
-> ReaderT (Either b d) m (Either c d)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((Either b d -> m (Either c d))
 -> ReaderT (Either b d) m (Either c d))
-> (Either b d -> m (Either c d))
-> ReaderT (Either b d) m (Either c d)
forall a b. (a -> b) -> a -> b
$! (b -> m (Either c d))
-> (d -> m (Either c d)) -> Either b d -> m (Either c d)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((c -> Either c d) -> m c -> m (Either c d)
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> Either c d
forall a b. a -> Either a b
Left (m c -> m (Either c d)) -> (b -> m c) -> b -> m (Either c d)
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
. ReaderT b m c -> b -> m c
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT b m c
ma) (Either c d -> m (Either c d)
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Either c d -> m (Either c d))
-> (d -> Either c d) -> d -> m (Either c d)
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
. d -> Either c d
forall a b. b -> Either a b
Right)
  {-# INLINE left #-}

  right :: forall b c d.
Automaton m b c -> Automaton m (Either d b) (Either d c)
right (Automaton (Stateful (StreamT {s
state :: ()
state :: s
state, s -> ReaderT b m (Result s c)
step :: ()
step :: s -> ReaderT b m (Result s c)
step}))) =
    OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
-> Automaton m (Either d b) (Either d c)
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
 -> Automaton m (Either d b) (Either d c))
-> OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
-> Automaton m (Either d b) (Either d c)
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT (Either d b) m) (Either d c)
-> OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT (Either d b) m) (Either d c)
 -> OptimizedStreamT (ReaderT (Either d b) m) (Either d c))
-> StreamT (ReaderT (Either d b) m) (Either d c)
-> OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { s
state :: s
state :: s
state
          , step :: s -> ReaderT (Either d b) m (Result s (Either d c))
step = \s
s -> (Either d b -> m (Result s (Either d c)))
-> ReaderT (Either d b) m (Result s (Either d c))
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((Either d b -> m (Result s (Either d c)))
 -> ReaderT (Either d b) m (Result s (Either d c)))
-> (Either d b -> m (Result s (Either d c)))
-> ReaderT (Either d b) m (Result s (Either d c))
forall a b. (a -> b) -> a -> b
$ (d -> m (Result s (Either d c)))
-> (b -> m (Result s (Either d c)))
-> Either d b
-> m (Result s (Either d c))
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Result s (Either d c) -> m (Result s (Either d c))
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Result s (Either d c) -> m (Result s (Either d c)))
-> (d -> Result s (Either d c)) -> d -> m (Result s (Either d c))
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 -> Either d c -> Result s (Either d c)
forall s a. s -> a -> Result s a
Result s
s (Either d c -> Result s (Either d c))
-> (d -> Either d c) -> d -> Result s (Either d c)
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
. d -> Either d c
forall a b. a -> Either a b
Left) ((Result s c -> Result s (Either d c))
-> m (Result s c) -> m (Result s (Either d c))
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((c -> Either d c) -> Result s c -> Result s (Either d c)
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> Either d c
forall a b. b -> Either a b
Right) (m (Result s c) -> m (Result s (Either d c)))
-> (b -> m (Result s c)) -> b -> m (Result s (Either d c))
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
. ReaderT b m (Result s c) -> b -> m (Result s c)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT b m (Result s c)
step s
s))
          }
  right (Automaton (Stateless ReaderT b m c
ma)) = OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
-> Automaton m (Either d b) (Either d c)
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
 -> Automaton m (Either d b) (Either d c))
-> OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
-> Automaton m (Either d b) (Either d c)
forall a b. (a -> b) -> a -> b
$! ReaderT (Either d b) m (Either d c)
-> OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT (Either d b) m (Either d c)
 -> OptimizedStreamT (ReaderT (Either d b) m) (Either d c))
-> ReaderT (Either d b) m (Either d c)
-> OptimizedStreamT (ReaderT (Either d b) m) (Either d c)
forall a b. (a -> b) -> a -> b
$! (Either d b -> m (Either d c))
-> ReaderT (Either d b) m (Either d c)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((Either d b -> m (Either d c))
 -> ReaderT (Either d b) m (Either d c))
-> (Either d b -> m (Either d c))
-> ReaderT (Either d b) m (Either d c)
forall a b. (a -> b) -> a -> b
$! (d -> m (Either d c))
-> (b -> m (Either d c)) -> Either d b -> m (Either d c)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Either d c -> m (Either d c)
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Either d c -> m (Either d c))
-> (d -> Either d c) -> d -> m (Either d c)
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
. d -> Either d c
forall a b. a -> Either a b
Left) ((c -> Either d c) -> m c -> m (Either d c)
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> Either d c
forall a b. b -> Either a b
Right (m c -> m (Either d c)) -> (b -> m c) -> b -> m (Either d c)
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
. ReaderT b m c -> b -> m c
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT b m c
ma)
  {-# INLINE right #-}

-- | Caution, this can make your program hang. Try to use 'feedback' or 'unfold' where possible, or combine 'loop' with 'delay'.
instance (MonadFix m) => ArrowLoop (Automaton m) where
  loop :: forall b d c. Automaton m (b, d) (c, d) -> Automaton m b c
loop (Automaton (Stateless ReaderT (b, d) m (c, d)
ma)) = OptimizedStreamT (ReaderT b m) c -> Automaton m b c
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT b m) c -> Automaton m b c)
-> OptimizedStreamT (ReaderT b m) c -> Automaton m b c
forall a b. (a -> b) -> a -> b
$! ReaderT b m c -> OptimizedStreamT (ReaderT b m) c
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT b m c -> OptimizedStreamT (ReaderT b m) c)
-> ReaderT b m c -> OptimizedStreamT (ReaderT b m) c
forall a b. (a -> b) -> a -> b
$! (b -> m c) -> ReaderT b m c
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT (\b
b -> (c, d) -> c
forall a b. (a, b) -> a
fst ((c, d) -> c) -> m (c, d) -> m c
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ((c, d) -> m (c, d)) -> m (c, d)
forall a. (a -> m a) -> m a
forall (m :: Type -> Type) a. MonadFix m => (a -> m a) -> m a
mfix (((d -> m (c, d)) -> ((c, d) -> d) -> (c, d) -> m (c, d)
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
. (c, d) -> d
forall a b. (a, b) -> b
snd) ((d -> m (c, d)) -> (c, d) -> m (c, d))
-> (d -> m (c, d)) -> (c, d) -> m (c, d)
forall a b. (a -> b) -> a -> b
$ ((b -> d -> m (c, d)) -> b -> d -> m (c, d)
forall a b. (a -> b) -> a -> b
$ b
b) ((b -> d -> m (c, d)) -> d -> m (c, d))
-> (b -> d -> m (c, d)) -> d -> m (c, d)
forall a b. (a -> b) -> a -> b
$ ((b, d) -> m (c, d)) -> b -> d -> m (c, d)
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (((b, d) -> m (c, d)) -> b -> d -> m (c, d))
-> ((b, d) -> m (c, d)) -> b -> d -> m (c, d)
forall a b. (a -> b) -> a -> b
$ ReaderT (b, d) m (c, d) -> (b, d) -> m (c, d)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (b, d) m (c, d)
ma))
  loop (Automaton (Stateful (StreamT {s
state :: ()
state :: s
state, s -> ReaderT (b, d) m (Result s (c, d))
step :: ()
step :: s -> ReaderT (b, d) m (Result s (c, d))
step}))) =
    OptimizedStreamT (ReaderT b m) c -> Automaton m b c
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT b m) c -> Automaton m b c)
-> OptimizedStreamT (ReaderT b m) c -> Automaton m b c
forall a b. (a -> b) -> a -> b
$!
      StreamT (ReaderT b m) c -> OptimizedStreamT (ReaderT b m) c
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT b m) c -> OptimizedStreamT (ReaderT b m) c)
-> StreamT (ReaderT b m) c -> OptimizedStreamT (ReaderT b m) c
forall a b. (a -> b) -> a -> b
$!
        StreamT
          { s
state :: s
state :: s
state
          , step :: s -> ReaderT b m (Result s c)
step = \s
s -> (b -> m (Result s c)) -> ReaderT b m (Result s c)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((b -> m (Result s c)) -> ReaderT b m (Result s c))
-> (b -> m (Result s c)) -> ReaderT b m (Result s c)
forall a b. (a -> b) -> a -> b
$ \b
b -> ((c, d) -> c) -> Result s (c, d) -> Result s c
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (c, d) -> c
forall a b. (a, b) -> a
fst (Result s (c, d) -> Result s c)
-> m (Result s (c, d)) -> m (Result s c)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Result s (c, d) -> m (Result s (c, d))) -> m (Result s (c, d))
forall a. (a -> m a) -> m a
forall (m :: Type -> Type) a. MonadFix m => (a -> m a) -> m a
mfix (((d -> m (Result s (c, d)))
-> (Result s (c, d) -> d) -> Result s (c, d) -> m (Result s (c, d))
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
. ((c, d) -> d
forall a b. (a, b) -> b
snd ((c, d) -> d)
-> (Result s (c, d) -> (c, d)) -> Result s (c, d) -> d
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
. Result s (c, d) -> (c, d)
forall s a. Result s a -> a
output)) ((d -> m (Result s (c, d)))
 -> Result s (c, d) -> m (Result s (c, d)))
-> (d -> m (Result s (c, d)))
-> Result s (c, d)
-> m (Result s (c, d))
forall a b. (a -> b) -> a -> b
$ ((b -> d -> m (Result s (c, d))) -> b -> d -> m (Result s (c, d))
forall a b. (a -> b) -> a -> b
$ b
b) ((b -> d -> m (Result s (c, d))) -> d -> m (Result s (c, d)))
-> (b -> d -> m (Result s (c, d))) -> d -> m (Result s (c, d))
forall a b. (a -> b) -> a -> b
$ ((b, d) -> m (Result s (c, d))) -> b -> d -> m (Result s (c, d))
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (((b, d) -> m (Result s (c, d))) -> b -> d -> m (Result s (c, d)))
-> ((b, d) -> m (Result s (c, d))) -> b -> d -> m (Result s (c, d))
forall a b. (a -> b) -> a -> b
$ ReaderT (b, d) m (Result s (c, d)) -> (b, d) -> m (Result s (c, d))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT (b, d) m (Result s (c, d))
 -> (b, d) -> m (Result s (c, d)))
-> ReaderT (b, d) m (Result s (c, d))
-> (b, d)
-> m (Result s (c, d))
forall a b. (a -> b) -> a -> b
$ s -> ReaderT (b, d) m (Result s (c, d))
step s
s)
          }
  {-# INLINE loop #-}

instance (Monad m, Alternative m) => ArrowZero (Automaton m) where
  zeroArrow :: forall b c. Automaton m b c
zeroArrow = Automaton m b c
forall a. Automaton m b a
forall (f :: Type -> Type) a. Alternative f => f a
empty

instance (Monad m, Alternative m) => ArrowPlus (Automaton m) where
  <+> :: forall b c. Automaton m b c -> Automaton m b c -> Automaton m b c
(<+>) = Automaton m b c -> Automaton m b c -> Automaton m b c
forall a. Automaton m b a -> Automaton m b a -> Automaton m b a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
(<|>)

-- | Consume an input and produce output effectfully, without keeping internal state
arrM :: (Functor m) => (a -> m b) -> Automaton m a b
arrM :: forall (m :: Type -> Type) a b.
Functor m =>
(a -> m b) -> Automaton m a b
arrM a -> m b
f = OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) b -> Automaton m a b)
-> OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall a b. (a -> b) -> a -> b
$! ReaderT a m b -> OptimizedStreamT (ReaderT a m) b
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
StreamOptimized.constM (ReaderT a m b -> OptimizedStreamT (ReaderT a m) b)
-> ReaderT a m b -> OptimizedStreamT (ReaderT a m) b
forall a b. (a -> b) -> a -> b
$! (a -> m b) -> ReaderT a m b
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT a -> m b
f
{-# INLINE arrM #-}

-- | Produce output effectfully, without keeping internal state
constM :: (Functor m) => m b -> Automaton m a b
constM :: forall (m :: Type -> Type) b a. Functor m => m b -> Automaton m a b
constM = (a -> m b) -> Automaton m a b
forall (m :: Type -> Type) a b.
Functor m =>
(a -> m b) -> Automaton m a b
arrM ((a -> m b) -> Automaton m a b)
-> (m b -> a -> m b) -> m b -> Automaton m a b
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 b -> a -> m b
forall a b. a -> b -> a
const
{-# INLINE constM #-}

-- | Apply an arbitrary monad morphism to an automaton.
hoistS :: (Monad m) => (forall x. m x -> n x) -> Automaton m a b -> Automaton n a b
hoistS :: forall (m :: Type -> Type) (n :: Type -> Type) a b.
Monad m =>
(forall x. m x -> n x) -> Automaton m a b -> Automaton n a b
hoistS forall x. m x -> n x
morph (Automaton OptimizedStreamT (ReaderT a m) b
automaton) = OptimizedStreamT (ReaderT a n) b -> Automaton n a b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a n) b -> Automaton n a b)
-> OptimizedStreamT (ReaderT a n) b -> Automaton n a b
forall a b. (a -> b) -> a -> b
$ (forall a. ReaderT a m a -> ReaderT a n a)
-> OptimizedStreamT (ReaderT a m) b
-> OptimizedStreamT (ReaderT a n) b
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 -> n a) -> ReaderT a m a -> ReaderT a n a
forall (m :: Type -> Type) a (n :: Type -> Type) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT m a -> n a
forall x. m x -> n x
morph) OptimizedStreamT (ReaderT a m) b
automaton
{-# INLINE hoistS #-}

-- | Lift the monad of an automaton to a transformer.
liftS :: (MonadTrans t, Monad m, Functor (t m)) => Automaton m a b -> Automaton (t m) a b
liftS :: forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a
       b.
(MonadTrans t, Monad m, Functor (t m)) =>
Automaton m a b -> Automaton (t m) a b
liftS = (forall x. m x -> t m x) -> Automaton m a b -> Automaton (t m) a b
forall (m :: Type -> Type) (n :: Type -> Type) a b.
Monad m =>
(forall x. m x -> n x) -> Automaton m a b -> Automaton n a b
hoistS m x -> t m x
forall x. m x -> t m x
forall (m :: Type -> Type) a. Monad m => m a -> t m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
{-# INLINE liftS #-}

{- | Extend the internal state and feed back part of the output to the next input.

This is one of the fundamental ways to incorporate recursive dataflow in automata.
Given an automaton which consumes an additional input and produces an additional output,
the state of the automaton is extended by a further value.
This value is used as the additional input,
and the resulting additional output is stored in the internal state for the next step.
-}
feedback ::
  (Functor m) =>
  -- | The additional internal state
  c ->
  -- | The original automaton
  Automaton m (a, c) (b, c) ->
  Automaton m a b
feedback :: forall (m :: Type -> Type) c a b.
Functor m =>
c -> Automaton m (a, c) (b, c) -> Automaton m a b
feedback c
c (Automaton (Stateful StreamT {s
state :: ()
state :: s
state, s -> ReaderT (a, c) m (Result s (b, c))
step :: ()
step :: s -> ReaderT (a, c) m (Result s (b, c))
step})) =
  OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) b -> Automaton m a b)
-> OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall a b. (a -> b) -> a -> b
$!
    StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b)
-> StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b
forall a b. (a -> b) -> a -> b
$!
      StreamT
        { state :: JointState s c
state = s -> c -> JointState s c
forall a b. a -> b -> JointState a b
JointState s
state c
c
        , step :: JointState s c -> ReaderT a m (Result (JointState s c) b)
step = \(JointState s
s c
c) -> (a -> m (Result (JointState s c) b))
-> ReaderT a m (Result (JointState s c) b)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((a -> m (Result (JointState s c) b))
 -> ReaderT a m (Result (JointState s c) b))
-> (a -> m (Result (JointState s c) b))
-> ReaderT a m (Result (JointState s c) b)
forall a b. (a -> b) -> a -> b
$ \a
a -> (\(Result s
s (b
b, c
c)) -> JointState s c -> b -> Result (JointState s c) b
forall s a. s -> a -> Result s a
Result (s -> c -> JointState s c
forall a b. a -> b -> JointState a b
JointState s
s c
c) b
b) (Result s (b, c) -> Result (JointState s c) b)
-> m (Result s (b, c)) -> m (Result (JointState s c) b)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT (a, c) m (Result s (b, c)) -> (a, c) -> m (Result s (b, c))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT (a, c) m (Result s (b, c))
step s
s) (a
a, c
c)
        }
feedback c
state (Automaton (Stateless ReaderT (a, c) m (b, c)
m)) =
  OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) b -> Automaton m a b)
-> OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall a b. (a -> b) -> a -> b
$!
    StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b)
-> StreamT (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b
forall a b. (a -> b) -> a -> b
$!
      StreamT
        { c
state :: c
state :: c
state
        , step :: c -> ReaderT a m (Result c b)
step = \c
c -> (a -> m (Result c b)) -> ReaderT a m (Result c b)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((a -> m (Result c b)) -> ReaderT a m (Result c b))
-> (a -> m (Result c b)) -> ReaderT a m (Result c b)
forall a b. (a -> b) -> a -> b
$ \a
a -> (\(b
b, c
c) -> c -> b -> Result c b
forall s a. s -> a -> Result s a
Result c
c b
b) ((b, c) -> Result c b) -> m (b, c) -> m (Result c b)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT (a, c) m (b, c) -> (a, c) -> m (b, c)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (a, c) m (b, c)
m (a
a, c
c)
        }
{-# INLINE feedback #-}

-- * Running automata

{- | Run one step of an automaton.

This consumes an input value, performs a side effect, and returns an updated automaton together with an output value.
-}
stepAutomaton :: (Functor m) => Automaton m a b -> a -> m (Result (Automaton m a b) b)
stepAutomaton :: forall (m :: Type -> Type) a b.
Functor m =>
Automaton m a b -> a -> m (Result (Automaton m a b) b)
stepAutomaton (Automaton OptimizedStreamT (ReaderT a m) b
automatonT) a
a =
  ReaderT a m (Result (OptimizedStreamT (ReaderT a m) b) b)
-> a -> m (Result (OptimizedStreamT (ReaderT a m) b) b)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (OptimizedStreamT (ReaderT a m) b
-> ReaderT a m (Result (OptimizedStreamT (ReaderT a m) b) b)
forall (m :: Type -> Type) a.
Functor m =>
OptimizedStreamT m a -> m (Result (OptimizedStreamT m a) a)
stepOptimizedStream OptimizedStreamT (ReaderT a m) b
automatonT) a
a
    m (Result (OptimizedStreamT (ReaderT a m) b) b)
-> (Result (OptimizedStreamT (ReaderT a m) b) b
    -> Result (Automaton m a b) b)
-> m (Result (Automaton m a b) b)
forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> (OptimizedStreamT (ReaderT a m) b -> Automaton m a b)
-> Result (OptimizedStreamT (ReaderT a m) b) b
-> Result (Automaton m a b) b
forall s1 s2 a. (s1 -> s2) -> Result s1 a -> Result s2 a
mapResultState OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton
{-# INLINE stepAutomaton #-}

{- | Run an automaton with trivial input and output indefinitely.

If the input and output of an automaton does not contain information,
all of its meaning is in its effects.
This function runs the automaton indefinitely.
Since it will never return with a value, this function also has no output (its output is void).
The only way it can return is if @m@ includes some effect of termination,
e.g. 'Maybe' or 'Either' could terminate with a 'Nothing' or 'Left' value,
or 'IO' can raise an exception.
-}
reactimate :: (Monad m) => Automaton m () () -> m void
reactimate :: forall (m :: Type -> Type) void.
Monad m =>
Automaton m () () -> m void
reactimate (Automaton OptimizedStreamT (ReaderT () m) ()
automaton) = OptimizedStreamT m () -> m void
forall (m :: Type -> Type) void.
Monad m =>
OptimizedStreamT m () -> m void
StreamOptimized.reactimate (OptimizedStreamT m () -> m void)
-> OptimizedStreamT m () -> m void
forall a b. (a -> b) -> a -> b
$ (forall a. ReaderT () m a -> m a)
-> OptimizedStreamT (ReaderT () m) () -> OptimizedStreamT m ()
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 (ReaderT () m a -> () -> m a
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
`runReaderT` ()) OptimizedStreamT (ReaderT () m) ()
automaton
{-# INLINE reactimate #-}

{- | Run an automaton with given input, for a given number of steps.

Especially for tests and batch processing,
it is useful to step an automaton with given input.
-}
embed ::
  (Monad m) =>
  -- | The automaton to run
  Automaton m a b ->
  -- | The input values
  [a] ->
  m [b]
embed :: forall (m :: Type -> Type) a b.
Monad m =>
Automaton m a b -> [a] -> m [b]
embed (Automaton (Stateful StreamT {s
state :: ()
state :: s
state, s -> ReaderT a m (Result s b)
step :: ()
step :: s -> ReaderT a m (Result s b)
step})) = s -> [a] -> m [b]
go s
state
  where
    go :: s -> [a] -> m [b]
go s
_s [] = [b] -> m [b]
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return []
    go s
s (a
a : [a]
as) = do
      Result s
s' b
b <- ReaderT a m (Result s b) -> a -> m (Result s b)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT a m (Result s b)
step s
s) a
a
      (b
b b -> [b] -> [b]
forall a. a -> [a] -> [a]
:) ([b] -> [b]) -> m [b] -> m [b]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> [a] -> m [b]
go s
s' [a]
as
embed (Automaton (Stateless ReaderT a m b
m)) = (a -> m b) -> [a] -> m [b]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> [a] -> m [b]
mapM ((a -> m b) -> [a] -> m [b]) -> (a -> m b) -> [a] -> m [b]
forall a b. (a -> b) -> a -> b
$ ReaderT a m b -> a -> m b
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT a m b
m

-- * Modifying automata

-- | Change the output type and effect of an automaton without changing its state type.
withAutomaton :: (Functor m1, Functor m2) => (forall s. (a1 -> m1 (Result s b1)) -> (a2 -> m2 (Result s b2))) -> Automaton m1 a1 b1 -> Automaton m2 a2 b2
withAutomaton :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) a1 b1 a2 b2.
(Functor m1, Functor m2) =>
(forall s. (a1 -> m1 (Result s b1)) -> a2 -> m2 (Result s b2))
-> Automaton m1 a1 b1 -> Automaton m2 a2 b2
withAutomaton forall s. (a1 -> m1 (Result s b1)) -> a2 -> m2 (Result s b2)
f = OptimizedStreamT (ReaderT a2 m2) b2 -> Automaton m2 a2 b2
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a2 m2) b2 -> Automaton m2 a2 b2)
-> (Automaton m1 a1 b1 -> OptimizedStreamT (ReaderT a2 m2) b2)
-> Automaton m1 a1 b1
-> Automaton m2 a2 b2
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
. (forall s.
 ReaderT a1 m1 (Result s b1) -> ReaderT a2 m2 (Result s b2))
-> OptimizedStreamT (ReaderT a1 m1) b1
-> OptimizedStreamT (ReaderT a2 m2) b2
forall (m :: Type -> Type) (n :: Type -> Type) a b.
(Functor m, Functor n) =>
(forall s. m (Result s a) -> n (Result s b))
-> OptimizedStreamT m a -> OptimizedStreamT n b
StreamOptimized.mapOptimizedStreamT ((a2 -> m2 (Result s b2)) -> ReaderT a2 m2 (Result s b2)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((a2 -> m2 (Result s b2)) -> ReaderT a2 m2 (Result s b2))
-> (ReaderT a1 m1 (Result s b1) -> a2 -> m2 (Result s b2))
-> ReaderT a1 m1 (Result s b1)
-> ReaderT a2 m2 (Result s b2)
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
. (a1 -> m1 (Result s b1)) -> a2 -> m2 (Result s b2)
forall s. (a1 -> m1 (Result s b1)) -> a2 -> m2 (Result s b2)
f ((a1 -> m1 (Result s b1)) -> a2 -> m2 (Result s b2))
-> (ReaderT a1 m1 (Result s b1) -> a1 -> m1 (Result s b1))
-> ReaderT a1 m1 (Result s b1)
-> a2
-> m2 (Result s b2)
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
. ReaderT a1 m1 (Result s b1) -> a1 -> m1 (Result s b1)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT) (OptimizedStreamT (ReaderT a1 m1) b1
 -> OptimizedStreamT (ReaderT a2 m2) b2)
-> (Automaton m1 a1 b1 -> OptimizedStreamT (ReaderT a1 m1) b1)
-> Automaton m1 a1 b1
-> OptimizedStreamT (ReaderT a2 m2) b2
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
. Automaton m1 a1 b1 -> OptimizedStreamT (ReaderT a1 m1) b1
forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton
{-# INLINE withAutomaton #-}

instance (Monad m) => Profunctor (Automaton m) where
  dimap :: forall a b c d.
(a -> b) -> (c -> d) -> Automaton m b c -> Automaton m a d
dimap a -> b
f c -> d
g Automaton {OptimizedStreamT (ReaderT b m) c
getAutomaton :: forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton :: OptimizedStreamT (ReaderT b m) c
getAutomaton} = OptimizedStreamT (ReaderT a m) d -> Automaton m a d
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) d -> Automaton m a d)
-> OptimizedStreamT (ReaderT a m) d -> Automaton m a d
forall a b. (a -> b) -> a -> b
$ c -> d
g (c -> d)
-> OptimizedStreamT (ReaderT a m) c
-> OptimizedStreamT (ReaderT a m) d
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. ReaderT b m a -> ReaderT a m a)
-> OptimizedStreamT (ReaderT b m) c
-> OptimizedStreamT (ReaderT a m) c
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 ((a -> b) -> ReaderT b m a -> ReaderT a m a
forall r' r (m :: Type -> Type) a.
(r' -> r) -> ReaderT r m a -> ReaderT r' m a
withReaderT a -> b
f) OptimizedStreamT (ReaderT b m) c
getAutomaton
  lmap :: forall a b c. (a -> b) -> Automaton m b c -> Automaton m a c
lmap a -> b
f Automaton {OptimizedStreamT (ReaderT b m) c
getAutomaton :: forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton :: OptimizedStreamT (ReaderT b m) c
getAutomaton} = OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) c -> Automaton m a c)
-> OptimizedStreamT (ReaderT a m) c -> Automaton m a c
forall a b. (a -> b) -> a -> b
$ (forall a. ReaderT b m a -> ReaderT a m a)
-> OptimizedStreamT (ReaderT b m) c
-> OptimizedStreamT (ReaderT a m) c
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 ((a -> b) -> ReaderT b m a -> ReaderT a m a
forall r' r (m :: Type -> Type) a.
(r' -> r) -> ReaderT r m a -> ReaderT r' m a
withReaderT a -> b
f) OptimizedStreamT (ReaderT b m) c
getAutomaton
  rmap :: forall b c a. (b -> c) -> Automaton m a b -> Automaton m a c
rmap = (b -> c) -> Automaton m a b -> Automaton m a c
forall a b. (a -> b) -> Automaton m a a -> Automaton m a b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap

instance (Monad m) => Choice (Automaton m) where
  right' :: forall a b c.
Automaton m a b -> Automaton m (Either c a) (Either c b)
right' = Automaton m a b -> Automaton m (Either c a) (Either c b)
forall a b c.
Automaton m a b -> Automaton m (Either c a) (Either c b)
forall (a :: Type -> Type -> Type) b c d.
ArrowChoice a =>
a b c -> a (Either d b) (Either d c)
right
  left' :: forall a b c.
Automaton m a b -> Automaton m (Either a c) (Either b c)
left' = Automaton m a b -> Automaton m (Either a c) (Either b c)
forall a b c.
Automaton m a b -> Automaton m (Either a c) (Either b c)
forall (a :: Type -> Type -> Type) b c d.
ArrowChoice a =>
a b c -> a (Either b d) (Either c d)
left

instance (Monad m) => Strong (Automaton m) where
  second' :: forall a b c. Automaton m a b -> Automaton m (c, a) (c, b)
second' = Automaton m a b -> Automaton m (c, a) (c, b)
forall a b c. Automaton m a b -> Automaton m (c, a) (c, b)
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second
  first' :: forall a b c. Automaton m a b -> Automaton m (a, c) (b, c)
first' = Automaton m a b -> Automaton m (a, c) (b, c)
forall a b c. Automaton m a b -> Automaton m (a, c) (b, c)
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first

-- | Step an automaton several steps at once, depending on how long the input is.
instance (Monad m) => Traversing (Automaton m) where
  wander :: forall a b s t.
(forall (f :: Type -> Type).
 Applicative f =>
 (a -> f b) -> s -> f t)
-> Automaton m a b -> Automaton m s t
wander forall (f :: Type -> Type). Applicative f => (a -> f b) -> s -> f t
f Automaton {getAutomaton :: forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton = Stateful StreamT {s
state :: ()
state :: s
state, s -> ReaderT a m (Result s b)
step :: ()
step :: s -> ReaderT a m (Result s b)
step}} =
    Automaton
      { getAutomaton :: OptimizedStreamT (ReaderT s m) t
getAutomaton =
          StreamT (ReaderT s m) t -> OptimizedStreamT (ReaderT s m) t
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful
            StreamT
              { s
state :: s
state :: s
state
              , step :: s -> ReaderT s m (Result s t)
step =
                  s -> ReaderT a m (Result s b)
step
                    (s -> ReaderT a m (Result s b))
-> ((s -> ReaderT a m (Result s b)) -> s -> a -> m (Result s b))
-> s
-> a
-> m (Result s b)
forall a b. a -> (a -> b) -> b
& (ReaderT a m (Result s b) -> a -> m (Result s b))
-> (s -> ReaderT a m (Result s b)) -> s -> a -> m (Result s b)
forall a b. (a -> b) -> (s -> a) -> s -> b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ReaderT a m (Result s b) -> a -> m (Result s b)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT
                    (s -> a -> m (Result s b))
-> ((s -> a -> m (Result s b)) -> a -> s -> m (Result s b))
-> a
-> s
-> m (Result s b)
forall a b. a -> (a -> b) -> b
& (s -> a -> m (Result s b)) -> a -> s -> m (Result s b)
forall a b c. (a -> b -> c) -> b -> a -> c
flip
                    (a -> s -> m (Result s b))
-> ((a -> s -> m (Result s b)) -> a -> ResultStateT s m b)
-> a
-> ResultStateT s m b
forall a b. a -> (a -> b) -> b
& ((s -> m (Result s b)) -> ResultStateT s m b)
-> (a -> s -> m (Result s b)) -> a -> ResultStateT s m b
forall a b. (a -> b) -> (a -> a) -> a -> b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (s -> m (Result s b)) -> ResultStateT s m b
forall s (m :: Type -> Type) a.
(s -> m (Result s a)) -> ResultStateT s m a
ResultStateT
                    (a -> ResultStateT s m b)
-> ((a -> ResultStateT s m b) -> s -> ResultStateT s m t)
-> s
-> ResultStateT s m t
forall a b. a -> (a -> b) -> b
& (a -> ResultStateT s m b) -> s -> ResultStateT s m t
forall (f :: Type -> Type). Applicative f => (a -> f b) -> s -> f t
f
                    (s -> ResultStateT s m t)
-> ((s -> ResultStateT s m t) -> s -> s -> m (Result s t))
-> s
-> s
-> m (Result s t)
forall a b. a -> (a -> b) -> b
& (ResultStateT s m t -> s -> m (Result s t))
-> (s -> ResultStateT s m t) -> s -> s -> m (Result s t)
forall a b. (a -> b) -> (s -> a) -> s -> b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ResultStateT s m t -> s -> m (Result s t)
forall s (m :: Type -> Type) a.
ResultStateT s m a -> s -> m (Result s a)
getResultStateT
                    (s -> s -> m (Result s t))
-> ((s -> s -> m (Result s t)) -> s -> s -> m (Result s t))
-> s
-> s
-> m (Result s t)
forall a b. a -> (a -> b) -> b
& (s -> s -> m (Result s t)) -> s -> s -> m (Result s t)
forall a b c. (a -> b -> c) -> b -> a -> c
flip
                    (s -> s -> m (Result s t))
-> ((s -> s -> m (Result s t)) -> s -> ReaderT s m (Result s t))
-> s
-> ReaderT s m (Result s t)
forall a b. a -> (a -> b) -> b
& ((s -> m (Result s t)) -> ReaderT s m (Result s t))
-> (s -> s -> m (Result s t)) -> s -> ReaderT s m (Result s t)
forall a b. (a -> b) -> (s -> a) -> s -> b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (s -> m (Result s t)) -> ReaderT s m (Result s t)
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT
              }
      }
  wander forall (f :: Type -> Type). Applicative f => (a -> f b) -> s -> f t
f (Automaton (Stateless ReaderT a m b
m)) = OptimizedStreamT (ReaderT s m) t -> Automaton m s t
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT s m) t -> Automaton m s t)
-> OptimizedStreamT (ReaderT s m) t -> Automaton m s t
forall a b. (a -> b) -> a -> b
$ ReaderT s m t -> OptimizedStreamT (ReaderT s m) t
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT s m t -> OptimizedStreamT (ReaderT s m) t)
-> ReaderT s m t -> OptimizedStreamT (ReaderT s m) t
forall a b. (a -> b) -> a -> b
$ (s -> m t) -> ReaderT s m t
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT ((s -> m t) -> ReaderT s m t) -> (s -> m t) -> ReaderT s m t
forall a b. (a -> b) -> a -> b
$ (a -> m b) -> s -> m t
forall (f :: Type -> Type). Applicative f => (a -> f b) -> s -> f t
f ((a -> m b) -> s -> m t) -> (a -> m b) -> s -> m t
forall a b. (a -> b) -> a -> b
$ ReaderT a m b -> a -> m b
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT a m b
m
  {-# INLINE wander #-}

-- | Only step the automaton if the input is 'Just'.
mapMaybeS :: (Monad m) => Automaton m a b -> Automaton m (Maybe a) (Maybe b)
mapMaybeS :: forall (m :: Type -> Type) a b.
Monad m =>
Automaton m a b -> Automaton m (Maybe a) (Maybe b)
mapMaybeS = Automaton m a b -> Automaton m (Maybe a) (Maybe b)
forall (f :: Type -> Type) a b.
Traversable f =>
Automaton m a b -> Automaton m (f a) (f b)
forall (p :: Type -> Type -> Type) (f :: Type -> Type) a b.
(Traversing p, Traversable f) =>
p a b -> p (f a) (f b)
traverse'

-- | Use an 'Automaton' with a variable amount of input.
traverseS :: (Monad m, Traversable f) => Automaton m a b -> Automaton m (f a) (f b)
traverseS :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Monad m, Traversable f) =>
Automaton m a b -> Automaton m (f a) (f b)
traverseS = Automaton m a b -> Automaton m (f a) (f b)
forall (f :: Type -> Type) a b.
Traversable f =>
Automaton m a b -> Automaton m (f a) (f b)
forall (p :: Type -> Type -> Type) (f :: Type -> Type) a b.
(Traversing p, Traversable f) =>
p a b -> p (f a) (f b)
traverse'

-- | Like 'traverseS', discarding the output.
traverseS_ :: (Monad m, Traversable f) => Automaton m a b -> Automaton m (f a) ()
traverseS_ :: forall (m :: Type -> Type) (f :: Type -> Type) a b.
(Monad m, Traversable f) =>
Automaton m a b -> Automaton m (f a) ()
traverseS_ Automaton m a b
automaton = Automaton m a b -> Automaton m (f a) (f b)
forall (f :: Type -> Type) a b.
Traversable f =>
Automaton m a b -> Automaton m (f a) (f b)
forall (p :: Type -> Type -> Type) (f :: Type -> Type) a b.
(Traversing p, Traversable f) =>
p a b -> p (f a) (f b)
traverse' Automaton m a b
automaton Automaton m (f a) (f b)
-> Automaton m (f b) () -> Automaton m (f a) ()
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (f b -> ()) -> Automaton m (f b) ()
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr (() -> f b -> ()
forall a b. a -> b -> a
const ())

{- | Launch arbitrarily many copies of the automaton in parallel.

* The copies of the automaton are launched on demand as the input lists grow.
* The n-th copy will always receive the n-th input.
* If the input list has length n, the n+1-th automaton copy will not be stepped.

Caution: Uses memory of the order of the largest list that was ever input during runtime.
-}
parallely :: (Applicative m) => Automaton m a b -> Automaton m [a] [b]
parallely :: forall (m :: Type -> Type) a b.
Applicative m =>
Automaton m a b -> Automaton m [a] [b]
parallely Automaton {getAutomaton :: forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton = Stateful StreamT (ReaderT a m) b
stream} = OptimizedStreamT (ReaderT [a] m) [b] -> Automaton m [a] [b]
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT [a] m) [b] -> Automaton m [a] [b])
-> OptimizedStreamT (ReaderT [a] m) [b] -> Automaton m [a] [b]
forall a b. (a -> b) -> a -> b
$ StreamT (ReaderT [a] m) [b] -> OptimizedStreamT (ReaderT [a] m) [b]
forall (m :: Type -> Type) a. StreamT m a -> OptimizedStreamT m a
Stateful (StreamT (ReaderT [a] m) [b]
 -> OptimizedStreamT (ReaderT [a] m) [b])
-> StreamT (ReaderT [a] m) [b]
-> OptimizedStreamT (ReaderT [a] m) [b]
forall a b. (a -> b) -> a -> b
$ StreamT (ReaderT a m) b -> StreamT (ReaderT [a] m) [b]
forall (m :: Type -> Type) a b.
Applicative m =>
StreamT (ReaderT a m) b -> StreamT (ReaderT [a] m) [b]
parallely' StreamT (ReaderT a m) b
stream
  where
    parallely' :: (Applicative m) => StreamT (ReaderT a m) b -> StreamT (ReaderT [a] m) [b]
    parallely' :: forall (m :: Type -> Type) a b.
Applicative m =>
StreamT (ReaderT a m) b -> StreamT (ReaderT [a] m) [b]
parallely' StreamT {s
state :: ()
state :: s
state, s -> ReaderT a m (Result s b)
step :: ()
step :: s -> ReaderT a m (Result s b)
step} = (forall s. s -> JointState s s)
-> (forall {s}.
    (s -> ReaderT [a] m (Result s [b]))
    -> JointState s s -> ReaderT [a] m (Result (JointState s s) [b]))
-> StreamT (ReaderT [a] m) [b]
forall (m :: Type -> Type) (t :: Type -> Type) a.
Functor m =>
(forall s. s -> t s)
-> (forall s. (s -> m (Result s a)) -> t s -> m (Result (t s) a))
-> StreamT m a
fixStream (s -> s -> JointState s s
forall a b. a -> b -> JointState a b
JointState s
state) ((forall {s}.
  (s -> ReaderT [a] m (Result s [b]))
  -> JointState s s -> ReaderT [a] m (Result (JointState s s) [b]))
 -> StreamT (ReaderT [a] m) [b])
-> (forall {s}.
    (s -> ReaderT [a] m (Result s [b]))
    -> JointState s s -> ReaderT [a] m (Result (JointState s s) [b]))
-> StreamT (ReaderT [a] m) [b]
forall a b. (a -> b) -> a -> b
$ \s -> ReaderT [a] m (Result s [b])
fixstep jointState :: JointState s s
jointState@(JointState s
s s
fixstate) -> ([a] -> m (Result (JointState s s) [b]))
-> ReaderT [a] m (Result (JointState s s) [b])
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT (([a] -> m (Result (JointState s s) [b]))
 -> ReaderT [a] m (Result (JointState s s) [b]))
-> ([a] -> m (Result (JointState s s) [b]))
-> ReaderT [a] m (Result (JointState s s) [b])
forall a b. (a -> b) -> a -> b
$ \case
      [] -> Result (JointState s s) [b] -> m (Result (JointState s s) [b])
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Result (JointState s s) [b] -> m (Result (JointState s s) [b]))
-> Result (JointState s s) [b] -> m (Result (JointState s s) [b])
forall a b. (a -> b) -> a -> b
$! JointState s s -> [b] -> Result (JointState s s) [b]
forall s a. s -> a -> Result s a
Result JointState s s
jointState []
      (a
a : [a]
as) -> Result s ([b] -> [b])
-> Result s [b] -> Result (JointState s s) [b]
forall s1 a b s2.
Result s1 (a -> b) -> Result s2 a -> Result (JointState s1 s2) b
apResult (Result s ([b] -> [b])
 -> Result s [b] -> Result (JointState s s) [b])
-> (Result s b -> Result s ([b] -> [b]))
-> Result s b
-> Result s [b]
-> Result (JointState s s) [b]
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
. (b -> [b] -> [b]) -> Result s b -> Result s ([b] -> [b])
forall a b. (a -> b) -> Result s a -> Result s b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (:) (Result s b -> Result s [b] -> Result (JointState s s) [b])
-> m (Result s b)
-> m (Result s [b] -> Result (JointState s s) [b])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT a m (Result s b) -> a -> m (Result s b)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT a m (Result s b)
step s
s) a
a m (Result s [b] -> Result (JointState s s) [b])
-> m (Result s [b]) -> m (Result (JointState s s) [b])
forall a b. m (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> ReaderT [a] m (Result s [b]) -> [a] -> m (Result s [b])
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (s -> ReaderT [a] m (Result s [b])
fixstep s
fixstate) [a]
as
parallely Automaton {getAutomaton :: forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton = Stateless ReaderT a m b
f} = OptimizedStreamT (ReaderT [a] m) [b] -> Automaton m [a] [b]
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT [a] m) [b] -> Automaton m [a] [b])
-> OptimizedStreamT (ReaderT [a] m) [b] -> Automaton m [a] [b]
forall a b. (a -> b) -> a -> b
$ ReaderT [a] m [b] -> OptimizedStreamT (ReaderT [a] m) [b]
forall (m :: Type -> Type) a. m a -> OptimizedStreamT m a
Stateless (ReaderT [a] m [b] -> OptimizedStreamT (ReaderT [a] m) [b])
-> ReaderT [a] m [b] -> OptimizedStreamT (ReaderT [a] m) [b]
forall a b. (a -> b) -> a -> b
$ ([a] -> m [b]) -> ReaderT [a] m [b]
forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT (([a] -> m [b]) -> ReaderT [a] m [b])
-> ([a] -> m [b]) -> ReaderT [a] m [b]
forall a b. (a -> b) -> a -> b
$ (a -> m b) -> [a] -> m [b]
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((a -> m b) -> [a] -> m [b]) -> (a -> m b) -> [a] -> m [b]
forall a b. (a -> b) -> a -> b
$ ReaderT a m b -> a -> m b
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT a m b
f

-- | Given a transformation of streams, apply it to an automaton, without changing the input.
handleAutomaton_ :: (Monad m) => (forall m. (Monad m) => StreamT m a -> StreamT m b) -> Automaton m i a -> Automaton m i b
handleAutomaton_ :: forall (m :: Type -> Type) a b i.
Monad m =>
(forall (m :: Type -> Type). Monad m => StreamT m a -> StreamT m b)
-> Automaton m i a -> Automaton m i b
handleAutomaton_ forall (m :: Type -> Type). Monad m => StreamT m a -> StreamT m b
f = OptimizedStreamT (ReaderT i m) b -> Automaton m i b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT i m) b -> Automaton m i b)
-> (Automaton m i a -> OptimizedStreamT (ReaderT i m) b)
-> Automaton m i a
-> Automaton m i b
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
. (forall (m :: Type -> Type). Monad m => StreamT m a -> StreamT m b)
-> OptimizedStreamT (ReaderT i m) a
-> OptimizedStreamT (ReaderT i m) b
forall (n :: Type -> Type) a b.
Monad n =>
(forall (m :: Type -> Type). Monad m => StreamT m a -> StreamT m b)
-> OptimizedStreamT n a -> OptimizedStreamT n b
StreamOptimized.withOptimized StreamT m a -> StreamT m b
forall (m :: Type -> Type). Monad m => StreamT m a -> StreamT m b
f (OptimizedStreamT (ReaderT i m) a
 -> OptimizedStreamT (ReaderT i m) b)
-> (Automaton m i a -> OptimizedStreamT (ReaderT i m) a)
-> Automaton m i a
-> OptimizedStreamT (ReaderT i m) b
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
. Automaton m i a -> OptimizedStreamT (ReaderT i m) a
forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton

-- | Given a transformation of streams, apply it to an automaton. The input can be accessed through the 'ReaderT' effect.
handleAutomaton :: (Monad m) => (StreamT (ReaderT a m) b -> StreamT (ReaderT c n) d) -> Automaton m a b -> Automaton n c d
handleAutomaton :: forall (m :: Type -> Type) a b c (n :: Type -> Type) d.
Monad m =>
(StreamT (ReaderT a m) b -> StreamT (ReaderT c n) d)
-> Automaton m a b -> Automaton n c d
handleAutomaton StreamT (ReaderT a m) b -> StreamT (ReaderT c n) d
f = OptimizedStreamT (ReaderT c n) d -> Automaton n c d
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT c n) d -> Automaton n c d)
-> (Automaton m a b -> OptimizedStreamT (ReaderT c n) d)
-> Automaton m a b
-> Automaton n c d
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 (ReaderT a m) b -> StreamT (ReaderT c n) d)
-> OptimizedStreamT (ReaderT a m) b
-> OptimizedStreamT (ReaderT c n) d
forall (m :: Type -> Type) a (n :: Type -> Type) b.
Functor m =>
(StreamT m a -> StreamT n b)
-> OptimizedStreamT m a -> OptimizedStreamT n b
StreamOptimized.handleOptimized StreamT (ReaderT a m) b -> StreamT (ReaderT c n) d
f (OptimizedStreamT (ReaderT a m) b
 -> OptimizedStreamT (ReaderT c n) d)
-> (Automaton m a b -> OptimizedStreamT (ReaderT a m) b)
-> Automaton m a b
-> OptimizedStreamT (ReaderT c n) d
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
. Automaton m a b -> OptimizedStreamT (ReaderT a m) b
forall (m :: Type -> Type) a b.
Automaton m a b -> OptimizedStreamT (ReaderT a m) b
getAutomaton

-- | Buffer the output of an automaton. See 'Data.Stream.concatS'.
concatS :: (Monad m) => Automaton m () [b] -> Automaton m () b
concatS :: forall (m :: Type -> Type) b.
Monad m =>
Automaton m () [b] -> Automaton m () b
concatS (Automaton OptimizedStreamT (ReaderT () m) [b]
automaton) = OptimizedStreamT (ReaderT () m) b -> Automaton m () b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT () m) b -> Automaton m () b)
-> OptimizedStreamT (ReaderT () m) b -> Automaton m () b
forall a b. (a -> b) -> a -> b
$ OptimizedStreamT (ReaderT () m) [b]
-> OptimizedStreamT (ReaderT () m) b
forall (m :: Type -> Type) a.
Monad m =>
OptimizedStreamT m [a] -> OptimizedStreamT m a
Data.Stream.Optimized.concatS OptimizedStreamT (ReaderT () m) [b]
automaton

-- * Examples

-- | Pass through a value unchanged, and perform a side effect depending on it
withSideEffect ::
  (Monad m) =>
  -- | For every value passing through the automaton, this function is called and the resulting side effect performed.
  (a -> m b) ->
  Automaton m a a
withSideEffect :: forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> Automaton m a a
withSideEffect a -> m b
f = (Automaton m a a
forall a. Automaton m a a
forall {k} (cat :: k -> k -> Type) (a :: k).
Category cat =>
cat a a
id Automaton m a a -> Automaton m a b -> Automaton m a (a, b)
forall b c c'.
Automaton m b c -> Automaton m b c' -> Automaton m b (c, c')
forall (a :: Type -> Type -> Type) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (a -> m b) -> Automaton m a b
forall (m :: Type -> Type) a b.
Functor m =>
(a -> m b) -> Automaton m a b
arrM a -> m b
f) Automaton m a (a, b) -> Automaton m (a, b) a -> Automaton 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
>>> ((a, b) -> a) -> Automaton m (a, b) a
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr (a, b) -> a
forall a b. (a, b) -> a
fst

-- | Accumulate the input, output the accumulator.
accumulateWith ::
  (Monad m) =>
  -- | The accumulation function
  (a -> b -> b) ->
  -- | The initial accumulator
  b ->
  Automaton m a b
accumulateWith :: forall (m :: Type -> Type) a b.
Monad m =>
(a -> b -> b) -> b -> Automaton m a b
accumulateWith a -> b -> b
f b
state = b -> (a -> b -> Result b b) -> Automaton m a b
forall (m :: Type -> Type) s a b.
Applicative m =>
s -> (a -> s -> Result s b) -> Automaton m a b
unfold b
state ((a -> b -> Result b b) -> Automaton m a b)
-> (a -> b -> Result b b) -> Automaton m a b
forall a b. (a -> b) -> a -> b
$ \a
a b
b -> let b' :: b
b' = a -> b -> b
f a
a b
b in b -> b -> Result b b
forall s a. s -> a -> Result s a
Result b
b' b
b'

-- | Like 'accumulateWith', with 'mappend' as the accumulation function.
mappendFrom :: (Monoid w, Monad m) => w -> Automaton m w w
mappendFrom :: forall w (m :: Type -> Type).
(Monoid w, Monad m) =>
w -> Automaton m w w
mappendFrom = (w -> w -> w) -> w -> Automaton m w w
forall (m :: Type -> Type) a b.
Monad m =>
(a -> b -> b) -> b -> Automaton m a b
accumulateWith w -> w -> w
forall a. Monoid a => a -> a -> a
mappend

-- | Delay the input by one step.
delay ::
  (Applicative m) =>
  -- | The value to output on the first step
  a ->
  Automaton m a a
delay :: forall (m :: Type -> Type) a. Applicative m => a -> Automaton m a a
delay a
a0 = a -> (a -> a -> Result a a) -> Automaton m a a
forall (m :: Type -> Type) s a b.
Applicative m =>
s -> (a -> s -> Result s b) -> Automaton m a b
unfold a
a0 ((a -> a -> Result a a) -> Automaton m a a)
-> (a -> a -> Result a a) -> Automaton m a a
forall a b. (a -> b) -> a -> b
$ \a
aIn a
aState -> a -> a -> Result a a
forall s a. s -> a -> Result s a
Result a
aIn a
aState

{- | Delay an automaton by one step by prepending one value to the output.

On the first step, the given initial output is returned.
On all subsequent steps, the automaton is stepped with the previous input.
-}
prepend :: (Monad m) => b -> Automaton m a b -> Automaton m a b
prepend :: forall (m :: Type -> Type) b a.
Monad m =>
b -> Automaton m a b -> Automaton m a b
prepend b
b0 Automaton m a b
automaton = proc a
a -> do
  Either b a
eab <- Either b a -> Automaton m (Either b a) (Either b a)
forall (m :: Type -> Type) a. Applicative m => a -> Automaton m a a
delay (b -> Either b a
forall a b. a -> Either a b
Left b
b0) -< a -> Either b a
forall a b. b -> Either a b
Right a
a
  case Either b a
eab of
    Left b
b -> Automaton m b b
forall (a :: Type -> Type -> Type) b. Arrow a => a b b
returnA -< b
b
    Right a
a -> Automaton m a b
automaton -< a
a

-- | Like 'mappendFrom', initialised at 'mempty'.
mappendS :: (Monoid w, Monad m) => Automaton m w w
mappendS :: forall w (m :: Type -> Type).
(Monoid w, Monad m) =>
Automaton m w w
mappendS = w -> Automaton m w w
forall w (m :: Type -> Type).
(Monoid w, Monad m) =>
w -> Automaton m w w
mappendFrom w
forall a. Monoid a => a
mempty

-- | Sum up all inputs so far, with an explicit initial value.
sumFrom :: (VectorSpace v s, Monad m) => v -> Automaton m v v
sumFrom :: forall v s (m :: Type -> Type).
(VectorSpace v s, Monad m) =>
v -> Automaton m v v
sumFrom = (v -> v -> v) -> v -> Automaton m v v
forall (m :: Type -> Type) a b.
Monad m =>
(a -> b -> b) -> b -> Automaton m a b
accumulateWith v -> v -> v
forall v a. VectorSpace v a => v -> v -> v
(^+^)

-- | Like 'sumFrom', initialised at 0.
sumS :: (Monad m, VectorSpace v s) => Automaton m v v
sumS :: forall (m :: Type -> Type) v s.
(Monad m, VectorSpace v s) =>
Automaton m v v
sumS = v -> Automaton m v v
forall v s (m :: Type -> Type).
(VectorSpace v s, Monad m) =>
v -> Automaton m v v
sumFrom v
forall v a. VectorSpace v a => v
zeroVector

-- | Sum up all inputs so far, initialised at 0.
sumN :: (Monad m, Num a) => Automaton m a a
sumN :: forall (m :: Type -> Type) a. (Monad m, Num a) => Automaton m a a
sumN = (a -> Sum a) -> Automaton m a (Sum a)
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr a -> Sum a
forall a. a -> Sum a
Sum Automaton m a (Sum a) -> Automaton m (Sum a) a -> Automaton 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
>>> Automaton m (Sum a) (Sum a)
forall w (m :: Type -> Type).
(Monoid w, Monad m) =>
Automaton m w w
mappendS Automaton m (Sum a) (Sum a)
-> Automaton m (Sum a) a -> Automaton m (Sum 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
>>> (Sum a -> a) -> Automaton m (Sum a) a
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr Sum a -> a
forall a. Sum a -> a
getSum

-- | Count the natural numbers, beginning at 1.
count :: (Num n, Monad m) => Automaton m a n
count :: forall n (m :: Type -> Type) a. (Num n, Monad m) => Automaton m a n
count = n -> Automaton m (a, n) (n, n) -> Automaton m a n
forall (m :: Type -> Type) c a b.
Functor m =>
c -> Automaton m (a, c) (b, c) -> Automaton m a b
feedback n
0 (Automaton m (a, n) (n, n) -> Automaton m a n)
-> Automaton m (a, n) (n, n) -> Automaton m a n
forall a b. (a -> b) -> a -> b
$! ((a, n) -> (n, n)) -> Automaton m (a, n) (n, n)
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr (\(a
_, n
n) -> let n' :: n
n' = n
n n -> n -> n
forall a. Num a => a -> a -> a
+ n
1 in (n
n', n
n'))

-- | Remembers the last 'Just' value, defaulting to the given initialisation value.
lastS :: (Monad m) => a -> Automaton m (Maybe a) a
lastS :: forall (m :: Type -> Type) a.
Monad m =>
a -> Automaton m (Maybe a) a
lastS a
a = (Maybe a -> Last a) -> Automaton m (Maybe a) (Last a)
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr Maybe a -> Last a
forall a. Maybe a -> Last a
Last Automaton m (Maybe a) (Last a)
-> Automaton m (Last a) a -> Automaton m (Maybe 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
>>> Automaton m (Last a) (Last a)
forall w (m :: Type -> Type).
(Monoid w, Monad m) =>
Automaton m w w
mappendS Automaton m (Last a) (Last a)
-> Automaton m (Last a) a -> Automaton m (Last 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
>>> (Last a -> a) -> Automaton m (Last a) a
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr (Last a -> Maybe a
forall a. Last a -> Maybe a
getLast (Last a -> Maybe a) -> (Maybe a -> a) -> Last 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
>>> a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
a)