packages feed

machinecell 3.3.2 → 4.0.0

raw patch · 23 files changed

+3103/−2534 lines, 23 filesdep +doctestdep ~arrowsdep ~basedep ~freePVP ok

version bump matches the API change (PVP)

Dependencies added: doctest

Dependency ranges changed: arrows, base, free, machinecell, mtl, profunctors, semigroups, transformers

API changes (from Hackage documentation)

- Control.Arrow.Machine.Misc.Discrete: instance (Control.Arrow.ArrowApply a, GHC.Num.Num o) => GHC.Num.Num (Control.Arrow.Machine.Misc.Discrete.Alg a i o)
- Control.Arrow.Machine.Misc.Discrete: instance Control.Arrow.ArrowApply a => GHC.Base.Applicative (Control.Arrow.Machine.Misc.Discrete.Alg a i)
- Control.Arrow.Machine.Misc.Discrete: instance Control.Arrow.ArrowApply a => GHC.Base.Functor (Control.Arrow.Machine.Misc.Discrete.Alg a i)
- Control.Arrow.Machine.Types: ExecInfo :: fa -> Bool -> Bool -> ExecInfo fa
- Control.Arrow.Machine.Types: [hasConsumed] :: ExecInfo fa -> Bool
- Control.Arrow.Machine.Types: [hasStopped] :: ExecInfo fa -> Bool
- Control.Arrow.Machine.Types: [yields] :: ExecInfo fa -> fa
- Control.Arrow.Machine.Types: data ExecInfo fa
- Control.Arrow.Machine.Types: data ProcessA a b c
- Control.Arrow.Machine.Types: instance (Control.Arrow.ArrowApply a, Data.Traversable.Traversable col) => Control.Arrow.Machine.Types.Stepper a b (col c) (Control.Arrow.Machine.Types.PluralStep ext col a b c)
- Control.Arrow.Machine.Types: instance (GHC.Base.Monad m, GHC.Base.Alternative m) => GHC.Base.MonadPlus (Control.Arrow.Machine.Types.PlanT i o m)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Control.Arrow.Arrow (Control.Arrow.Machine.Types.ProcessA a)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Control.Arrow.ArrowChoice (Control.Arrow.Machine.Types.ProcessA a)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Control.Arrow.ArrowLoop (Control.Arrow.Machine.Types.ProcessA a)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Control.Arrow.Machine.Types.Stepper a b c (Control.Arrow.Machine.Types.ArrStep a b c)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Control.Arrow.Machine.Types.Stepper a b c (Control.Arrow.Machine.Types.CompositeStep a b c s1 s2)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Control.Arrow.Machine.Types.Stepper a b c (Control.Arrow.Machine.Types.IDStep a b c)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Control.Arrow.Machine.Types.Stepper a b c (Control.Arrow.Machine.Types.ParStep a b c s1 s2)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Control.Category.Category (Control.Arrow.Machine.Types.ProcessA a)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => Data.Profunctor.Unsafe.Profunctor (Control.Arrow.Machine.Types.ProcessA a)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => GHC.Base.Applicative (Control.Arrow.Machine.Types.ProcessA a i)
- Control.Arrow.Machine.Types: instance Control.Arrow.ArrowApply a => GHC.Base.Functor (Control.Arrow.Machine.Types.ProcessA a i)
- Control.Arrow.Machine.Types: instance Control.Arrow.Machine.Types.Stepper a b c (Control.Arrow.Machine.Types.ProcessA a b c)
- Control.Arrow.Machine.Types: instance GHC.Base.Alternative f => GHC.Base.Monoid (Control.Arrow.Machine.Types.ExecInfo (f a))
- Control.Arrow.Machine.Types: instance GHC.Base.Alternative m => GHC.Base.Alternative (Control.Arrow.Machine.Types.PlanT i o m)
- Control.Arrow.Machine.Types: instance GHC.Base.Monoid (Control.Arrow.Machine.Types.Builder a)
- Control.Arrow.Machine.Types: instance GHC.Classes.Eq fa => GHC.Classes.Eq (Control.Arrow.Machine.Types.ExecInfo fa)
- Control.Arrow.Machine.Types: instance GHC.Show.Show fa => GHC.Show.Show (Control.Arrow.Machine.Types.ExecInfo fa)
- Control.Arrow.Machine.Types: runOn :: (ArrowApply a, Monoid r, Foldable f) => (c -> r) -> ProcessA a (Event b) (Event c) -> a (f b) r
- Control.Arrow.Machine.Utils: echo :: ArrowApply a => ProcessA a (Event b) (Event b)
- Control.Arrow.Machine.Utils: filter :: ArrowApply a => a b Bool -> ProcessA a (Event b) (Event b)
+ Control.Arrow.Machine.Evolution: dSwitchAfter :: Monad m => ProcessT m i (o, Event r) -> Evolution i o m r
+ Control.Arrow.Machine.Evolution: dgSwitchAfter :: Monad m => ProcessT m i (p, r) -> ProcessT m (q, r) (o, Event t) -> ProcessT m p q -> Evolution i o m (ProcessT m p q, t)
+ Control.Arrow.Machine.Evolution: dkSwitchAfter :: Monad m => ProcessT m (i, o) (Event r) -> ProcessT m i o -> Evolution i o m (ProcessT m i o, r)
+ Control.Arrow.Machine.Evolution: evolve :: Evolution i o m Void -> ProcessT m i o
+ Control.Arrow.Machine.Evolution: finishWith :: Monad m => ProcessT m i o -> Evolution i o m r
+ Control.Arrow.Machine.Evolution: gSwitchAfter :: Monad m => ProcessT m i (p, r) -> ProcessT m (q, r) (o, Event t) -> ProcessT m p q -> Evolution i o m (ProcessT m p q, t)
+ Control.Arrow.Machine.Evolution: kSwitchAfter :: Monad m => ProcessT m (i, o) (Event r) -> ProcessT m i o -> Evolution i o m (ProcessT m i o, r)
+ Control.Arrow.Machine.Evolution: switchAfter :: Monad m => ProcessT m i (o, Event r) -> Evolution i o m r
+ Control.Arrow.Machine.Misc.Discrete: instance (GHC.Base.Monad m, GHC.Num.Num o) => GHC.Num.Num (Control.Arrow.Machine.Misc.Discrete.Alg m i o)
+ Control.Arrow.Machine.Misc.Discrete: instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Arrow.Machine.Misc.Discrete.Alg m i)
+ Control.Arrow.Machine.Misc.Discrete: instance GHC.Base.Monad m => GHC.Base.Functor (Control.Arrow.Machine.Misc.Discrete.Alg m i)
+ Control.Arrow.Machine.Types: Evolution :: Cont (ProcessT m i o) r -> Evolution i o m r
+ Control.Arrow.Machine.Types: ZeroEvent :: ZeroEvent
+ Control.Arrow.Machine.Types: [runEvolution] :: Evolution i o m r -> Cont (ProcessT m i o) r
+ Control.Arrow.Machine.Types: awaitProc :: (Monad m, Occasional o) => (a -> ProcessT m (Event a) o) -> ProcessT m (Event a) o -> ProcessT m (Event a) o
+ Control.Arrow.Machine.Types: burst :: Occasional a => Event Void -> a
+ Control.Arrow.Machine.Types: class MonadAwait m a | m -> a
+ Control.Arrow.Machine.Types: class MonadStop m
+ Control.Arrow.Machine.Types: class MonadYield m a | m -> a
+ Control.Arrow.Machine.Types: data ProcessT m b c
+ Control.Arrow.Machine.Types: data ZeroEvent
+ Control.Arrow.Machine.Types: instance (Control.Monad.IO.Class.MonadIO m, Control.Arrow.Machine.Types.Occasional o) => Control.Monad.IO.Class.MonadIO (Control.Arrow.Machine.Types.Evolution i o m)
+ Control.Arrow.Machine.Types: instance (GHC.Base.Monad m, Control.Arrow.Machine.Types.Occasional o) => Control.Arrow.Machine.Types.MonadAwait (Control.Arrow.Machine.Types.Evolution (Control.Arrow.Machine.Types.Event a) o m) a
+ Control.Arrow.Machine.Types: instance (GHC.Base.Monad m, Control.Arrow.Machine.Types.Occasional o) => Control.Arrow.Machine.Types.MonadStop (Control.Arrow.Machine.Types.Evolution i o m)
+ Control.Arrow.Machine.Types: instance (GHC.Base.Monad m, Data.Traversable.Traversable col) => Control.Arrow.Machine.Types.Stepper m b (col c) (Control.Arrow.Machine.Types.PluralStep ext col m b c)
+ Control.Arrow.Machine.Types: instance (GHC.Base.Monad m, GHC.Base.Monoid o) => GHC.Base.Monoid (Control.Arrow.Machine.Types.ProcessT m i o)
+ Control.Arrow.Machine.Types: instance Control.Arrow.Machine.Types.Occasional o => Control.Monad.Trans.Class.MonadTrans (Control.Arrow.Machine.Types.Evolution i o)
+ Control.Arrow.Machine.Types: instance Control.Arrow.Machine.Types.Occasional' Control.Arrow.Machine.Types.ZeroEvent
+ Control.Arrow.Machine.Types: instance Control.Arrow.Machine.Types.Stepper a b c (Control.Arrow.Machine.Types.ProcessT a b c)
+ Control.Arrow.Machine.Types: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Arrow.Machine.Types.PlanT i o m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Applicative (Control.Arrow.Machine.Types.Evolution i o m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Functor (Control.Arrow.Machine.Types.Evolution i o m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad (Control.Arrow.Machine.Types.Evolution i o m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Arrow (Control.Arrow.Machine.Types.ProcessT m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.ArrowChoice (Control.Arrow.Machine.Types.ProcessT m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.ArrowLoop (Control.Arrow.Machine.Types.ProcessT m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Machine.Types.MonadAwait (Control.Arrow.Machine.Types.PlanT i o m) i
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Machine.Types.MonadStop (Control.Arrow.Machine.Types.PlanT i o m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Machine.Types.MonadYield (Control.Arrow.Machine.Types.Evolution i (Control.Arrow.Machine.Types.Event a) m) a
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Machine.Types.MonadYield (Control.Arrow.Machine.Types.PlanT i o m) o
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Machine.Types.Stepper m b c (Control.Arrow.Machine.Types.ArrStep m b c)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Machine.Types.Stepper m b c (Control.Arrow.Machine.Types.CompositeStep m b c s1 s2)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Machine.Types.Stepper m b c (Control.Arrow.Machine.Types.IDStep m b c)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Arrow.Machine.Types.Stepper m b c (Control.Arrow.Machine.Types.ParStep m b c s1 s2)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Control.Category.Category (Control.Arrow.Machine.Types.ProcessT m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => Data.Profunctor.Unsafe.Profunctor (Control.Arrow.Machine.Types.ProcessT m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => GHC.Base.Alternative (Control.Arrow.Machine.Types.PlanT i o m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Arrow.Machine.Types.ProcessT m i)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => GHC.Base.Functor (Control.Arrow.Machine.Types.ProcessT m i)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monad m => GHC.Base.MonadPlus (Control.Arrow.Machine.Types.PlanT i o m)
+ Control.Arrow.Machine.Types: instance GHC.Base.Monoid Control.Arrow.Machine.Types.ZeroEvent
+ Control.Arrow.Machine.Types: instance GHC.Classes.Eq Control.Arrow.Machine.Types.ZeroEvent
+ Control.Arrow.Machine.Types: instance GHC.Enum.Bounded Control.Arrow.Machine.Types.ZeroEvent
+ Control.Arrow.Machine.Types: instance GHC.Enum.Enum Control.Arrow.Machine.Types.ZeroEvent
+ Control.Arrow.Machine.Types: instance GHC.Show.Show Control.Arrow.Machine.Types.ZeroEvent
+ Control.Arrow.Machine.Types: newtype Evolution i o m r
+ Control.Arrow.Machine.Types: packProc :: (Monad m, Occasional o) => m (ProcessT m i o) -> ProcessT m i o
+ Control.Arrow.Machine.Types: runT :: (Monad m, Foldable f) => (c -> m ()) -> ProcessT m (Event b) (Event c) -> f b -> m ()
+ Control.Arrow.Machine.Types: runT_ :: (Monad m, Foldable f) => ProcessT m (Event a) (Event b) -> f a -> m ()
+ Control.Arrow.Machine.Types: type ProcessA a = ProcessT (ArrowMonad a)
+ Control.Arrow.Machine.Types: yieldProc :: Monad m => a -> ProcessT m i (Event a) -> ProcessT m i (Event a)
+ Control.Arrow.Machine.Utils: fire :: Monad m => (b -> m c) -> ProcessT m (Event b) (Event c)
+ Control.Arrow.Machine.Utils: fire0 :: Monad m => m c -> ProcessT m (Event ()) (Event c)
- Control.Arrow.Machine.Misc.Discrete: Alg :: ProcessA a i (T o) -> Alg a i o
+ Control.Arrow.Machine.Misc.Discrete: Alg :: ProcessT m i (T o) -> Alg m i o
- Control.Arrow.Machine.Misc.Discrete: [eval] :: Alg a i o -> ProcessA a i (T o)
+ Control.Arrow.Machine.Misc.Discrete: [eval] :: Alg m i o -> ProcessT m i (T o)
- Control.Arrow.Machine.Misc.Discrete: accum :: ArrowApply a => b -> ProcessA a (Event (b -> b)) (T b)
+ Control.Arrow.Machine.Misc.Discrete: accum :: Monad m => b -> ProcessT m (Event (b -> b)) (T b)
- Control.Arrow.Machine.Misc.Discrete: arr :: ArrowApply a => (b -> c) -> ProcessA a (T b) (T c)
+ Control.Arrow.Machine.Misc.Discrete: arr :: Monad m => (b -> c) -> ProcessT m (T b) (T c)
- Control.Arrow.Machine.Misc.Discrete: arr2 :: ArrowApply a => (b1 -> b2 -> c) -> ProcessA a (T b1, T b2) (T c)
+ Control.Arrow.Machine.Misc.Discrete: arr2 :: Monad m => (b1 -> b2 -> c) -> ProcessT m (T b1, T b2) (T c)
- Control.Arrow.Machine.Misc.Discrete: arr3 :: ArrowApply a => (b1 -> b2 -> b3 -> c) -> ProcessA a (T b1, T b2, T b3) (T c)
+ Control.Arrow.Machine.Misc.Discrete: arr3 :: Monad m => (b1 -> b2 -> b3 -> c) -> ProcessT m (T b1, T b2, T b3) (T c)
- Control.Arrow.Machine.Misc.Discrete: arr4 :: ArrowApply a => (b1 -> b2 -> b3 -> b4 -> c) -> ProcessA a (T b1, T b2, T b3, T b4) (T c)
+ Control.Arrow.Machine.Misc.Discrete: arr4 :: Monad m => (b1 -> b2 -> b3 -> b4 -> c) -> ProcessT m (T b1, T b2, T b3, T b4) (T c)
- Control.Arrow.Machine.Misc.Discrete: arr5 :: ArrowApply a => (b1 -> b2 -> b3 -> b4 -> b5 -> c) -> ProcessA a (T b1, T b2, T b3, T b4, T b5) (T c)
+ Control.Arrow.Machine.Misc.Discrete: arr5 :: Monad m => (b1 -> b2 -> b3 -> b4 -> b5 -> c) -> ProcessT m (T b1, T b2, T b3, T b4, T b5) (T c)
- Control.Arrow.Machine.Misc.Discrete: asUpdater :: ArrowApply a => a b c -> ProcessA a (T b) (Event c)
+ Control.Arrow.Machine.Misc.Discrete: asUpdater :: Monad m => (b -> m c) -> ProcessT m (T b) (Event c)
- Control.Arrow.Machine.Misc.Discrete: constant :: ArrowApply a => c -> ProcessA a b (T c)
+ Control.Arrow.Machine.Misc.Discrete: constant :: Monad m => c -> ProcessT m b (T c)
- Control.Arrow.Machine.Misc.Discrete: dkSwitch :: ArrowApply a => ProcessA a b (T c) -> ProcessA a (b, T c) (Event t) -> (ProcessA a b (T c) -> t -> ProcessA a b (T c)) -> ProcessA a b (T c)
+ Control.Arrow.Machine.Misc.Discrete: dkSwitch :: Monad m => ProcessT m b (T c) -> ProcessT m (b, T c) (Event t) -> (ProcessT m b (T c) -> t -> ProcessT m b (T c)) -> ProcessT m b (T c)
- Control.Arrow.Machine.Misc.Discrete: edge :: ArrowApply a => ProcessA a (T b) (Event b)
+ Control.Arrow.Machine.Misc.Discrete: edge :: Monad m => ProcessT m (T b) (Event b)
- Control.Arrow.Machine.Misc.Discrete: fromEq :: (ArrowApply a, Eq b) => ProcessA a b (T b)
+ Control.Arrow.Machine.Misc.Discrete: fromEq :: (Monad m, Eq b) => ProcessT m b (T b)
- Control.Arrow.Machine.Misc.Discrete: hold :: ArrowApply a => b -> ProcessA a (Event b) (T b)
+ Control.Arrow.Machine.Misc.Discrete: hold :: Monad m => b -> ProcessT m (Event b) (T b)
- Control.Arrow.Machine.Misc.Discrete: kSwitch :: ArrowApply a => ProcessA a b (T c) -> ProcessA a (b, T c) (Event t) -> (ProcessA a b (T c) -> t -> ProcessA a b (T c)) -> ProcessA a b (T c)
+ Control.Arrow.Machine.Misc.Discrete: kSwitch :: Monad m => ProcessT m b (T c) -> ProcessT m (b, T c) (Event t) -> (ProcessT m b (T c) -> t -> ProcessT m b (T c)) -> ProcessT m b (T c)
- Control.Arrow.Machine.Misc.Discrete: newtype Alg a i o
+ Control.Arrow.Machine.Misc.Discrete: newtype Alg m i o
- Control.Arrow.Machine.Misc.Discrete: refer :: ArrowApply a => (e -> T b) -> Alg a e b
+ Control.Arrow.Machine.Misc.Discrete: refer :: Monad m => (e -> T b) -> Alg m e b
- Control.Arrow.Machine.Misc.Discrete: unsafeConstant :: ArrowApply a => c -> ProcessA a b (T c)
+ Control.Arrow.Machine.Misc.Discrete: unsafeConstant :: Monad m => c -> ProcessT m b (T c)
- Control.Arrow.Machine.Misc.Pump: intake :: ArrowApply a => ProcessA a (Event b, Event ()) (Duct b)
+ Control.Arrow.Machine.Misc.Pump: intake :: Monad m => ProcessT m (Event b, Event ()) (Duct b)
- Control.Arrow.Machine.Misc.Pump: outlet :: ArrowApply a => ProcessA a (Duct b, Event ()) (Event b)
+ Control.Arrow.Machine.Misc.Pump: outlet :: Monad m => ProcessT m (Duct b, Event ()) (Event b)
- Control.Arrow.Machine.Types: await :: Plan i o i
+ Control.Arrow.Machine.Types: await :: MonadAwait m a => m a
- Control.Arrow.Machine.Types: construct :: ArrowApply a => PlanT i o Identity r -> ProcessA a (Event i) (Event o)
+ Control.Arrow.Machine.Types: construct :: Monad m => PlanT i o Identity r -> ProcessT m (Event i) (Event o)
- Control.Arrow.Machine.Types: constructT :: (Monad m, ArrowApply a) => (forall b. m b -> a () b) -> PlanT i o m r -> ProcessA a (Event i) (Event o)
+ Control.Arrow.Machine.Types: constructT :: (Monad m) => PlanT i o m r -> ProcessT m (Event i) (Event o)
- Control.Arrow.Machine.Types: dSwitch :: ArrowApply a => ProcessA a b (c, Event t) -> (t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Types: dSwitch :: Monad m => ProcessT m b (c, Event t) -> (t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Types: dgSwitch :: ArrowApply a => ProcessA a b (p, r) -> ProcessA a p q -> ProcessA a (q, r) (c, Event t) -> (ProcessA a p q -> t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Types: dgSwitch :: Monad m => ProcessT m b (p, r) -> ProcessT m p q -> ProcessT m (q, r) (c, Event t) -> (ProcessT m p q -> t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Types: dkSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, c) (Event t) -> (ProcessA a b c -> t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Types: dkSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, c) (Event t) -> (ProcessT m b c -> t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Types: dpSwitch :: (ArrowApply a, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessA a ext c) -> ProcessA a (b, col c) (Event mng) -> (col (ProcessA a ext c) -> mng -> ProcessA a b (col c)) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Types: dpSwitch :: (Monad m, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessT m ext c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m ext c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c)
- Control.Arrow.Machine.Types: dpSwitchB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a (b, col c) (Event mng) -> (col (ProcessA a b c) -> mng -> ProcessA a b (col c)) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Types: dpSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m b c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c)
- Control.Arrow.Machine.Types: drSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, Event (ProcessA a b c)) c
+ Control.Arrow.Machine.Types: drSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, Event (ProcessT m b c)) c
- Control.Arrow.Machine.Types: drpSwitch :: (ArrowApply a, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessA a ext c) -> ProcessA a (b, Event (col (ProcessA a ext c) -> col (ProcessA a ext c))) (col c)
+ Control.Arrow.Machine.Types: drpSwitch :: (Monad m, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessT m ext c) -> ProcessT m (b, Event (col (ProcessT m ext c) -> col (ProcessT m ext c))) (col c)
- Control.Arrow.Machine.Types: drpSwitchB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a (b, Event (col (ProcessA a b c) -> col (ProcessA a b c))) (col c)
+ Control.Arrow.Machine.Types: drpSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, Event (col (ProcessT m b c) -> col (ProcessT m b c))) (col c)
- Control.Arrow.Machine.Types: fit :: (ArrowApply a, ArrowApply a') => (forall p q. a p q -> a' p q) -> ProcessA a b c -> ProcessA a' b c
+ Control.Arrow.Machine.Types: fit :: (Monad m, Monad m') => (forall p. m p -> m' p) -> ProcessT m b c -> ProcessT m' b c
- Control.Arrow.Machine.Types: fitW :: (ArrowApply a, ArrowApply a', Functor w) => (forall p. w p -> p) -> (forall p q. a p q -> a' (w p) q) -> ProcessA a b c -> ProcessA a' (w b) c
+ Control.Arrow.Machine.Types: fitW :: (Monad m, Monad m', Functor w) => (forall p. w p -> p) -> (forall p q. (p -> m q) -> w p -> m' q) -> ProcessT m b c -> ProcessT m' (w b) c
- Control.Arrow.Machine.Types: gSwitch :: ArrowApply a => ProcessA a b (p, r) -> ProcessA a p q -> ProcessA a (q, r) (c, Event t) -> (ProcessA a p q -> t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Types: gSwitch :: Monad m => ProcessT m b (p, r) -> ProcessT m p q -> ProcessT m (q, r) (c, Event t) -> (ProcessT m p q -> t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Types: kSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, c) (Event t) -> (ProcessA a b c -> t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Types: kSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, c) (Event t) -> (ProcessT m b c -> t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Types: muted :: (ArrowApply a, Occasional' b, Occasional c) => ProcessA a b c
+ Control.Arrow.Machine.Types: muted :: (Monad m, Occasional' b, Occasional c) => ProcessT m b c
- Control.Arrow.Machine.Types: pSwitch :: (ArrowApply a, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessA a ext c) -> ProcessA a (b, col c) (Event mng) -> (col (ProcessA a ext c) -> mng -> ProcessA a b (col c)) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Types: pSwitch :: (Monad m, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessT m ext c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m ext c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c)
- Control.Arrow.Machine.Types: pSwitchB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a (b, col c) (Event mng) -> (col (ProcessA a b c) -> mng -> ProcessA a b (col c)) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Types: pSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m b c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c)
- Control.Arrow.Machine.Types: par :: (ArrowApply a, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessA a ext c) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Types: par :: (Monad m, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessT m ext c) -> ProcessT m b (col c)
- Control.Arrow.Machine.Types: parB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Types: parB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m b (col c)
- Control.Arrow.Machine.Types: rSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, Event (ProcessA a b c)) c
+ Control.Arrow.Machine.Types: rSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, Event (ProcessT m b c)) c
- Control.Arrow.Machine.Types: repeatedly :: ArrowApply a => PlanT i o Identity r -> ProcessA a (Event i) (Event o)
+ Control.Arrow.Machine.Types: repeatedly :: Monad m => PlanT i o Identity r -> ProcessT m (Event i) (Event o)
- Control.Arrow.Machine.Types: repeatedlyT :: (Monad m, ArrowApply a) => (forall b. m b -> a () b) -> PlanT i o m r -> ProcessA a (Event i) (Event o)
+ Control.Arrow.Machine.Types: repeatedlyT :: Monad m => PlanT i o m r -> ProcessT m (Event i) (Event o)
- Control.Arrow.Machine.Types: rpSwitch :: (ArrowApply a, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessA a ext c) -> ProcessA a (b, Event (col (ProcessA a ext c) -> col (ProcessA a ext c))) (col c)
+ Control.Arrow.Machine.Types: rpSwitch :: (Monad m, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessT m ext c) -> ProcessT m (b, Event (col (ProcessT m ext c) -> col (ProcessT m ext c))) (col c)
- Control.Arrow.Machine.Types: rpSwitchB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a (b, Event (col (ProcessA a b c) -> col (ProcessA a b c))) (col c)
+ Control.Arrow.Machine.Types: rpSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, Event (col (ProcessT m b c) -> col (ProcessT m b c))) (col c)
- Control.Arrow.Machine.Types: run :: ArrowApply a => ProcessA a (Event b) (Event c) -> a [b] [c]
+ Control.Arrow.Machine.Types: run :: Foldable f => ProcessT Identity (Event a) (Event b) -> f a -> [b]
- Control.Arrow.Machine.Types: run_ :: ArrowApply a => ProcessA a (Event b) (Event c) -> a [b] ()
+ Control.Arrow.Machine.Types: run_ :: (Foldable f, ArrowApply a) => ProcessA a (Event b) (Event c) -> a (f b) ()
- Control.Arrow.Machine.Types: stepRun :: ArrowApply a => ProcessA a (Event b) (Event c) -> a b (ExecInfo [c], ProcessA a (Event b) (Event c))
+ Control.Arrow.Machine.Types: stepRun :: (Monad m, Monad m') => (forall p. m p -> m' p) -> (b -> m' ()) -> (Maybe a -> m' ()) -> ProcessT m (Event a) (Event b) -> a -> m' (ProcessT m (Event a) (Event b))
- Control.Arrow.Machine.Types: stepYield :: ArrowApply a => ProcessA a (Event b) (Event c) -> a b (ExecInfo (Maybe c), ProcessA a (Event b) (Event c))
+ Control.Arrow.Machine.Types: stepYield :: (Monad m, Monad m') => (forall p. m p -> m' p) -> m' a -> m' () -> ProcessT m (Event a) (Event b) -> m' (Maybe b, ProcessT m (Event a) (Event b))
- Control.Arrow.Machine.Types: stop :: Plan i o a
+ Control.Arrow.Machine.Types: stop :: MonadStop m => m a
- Control.Arrow.Machine.Types: stopped :: (ArrowApply a, Occasional c) => ProcessA a b c
+ Control.Arrow.Machine.Types: stopped :: (Monad m, Occasional o) => ProcessT m i o
- Control.Arrow.Machine.Types: switch :: ArrowApply a => ProcessA a b (c, Event t) -> (t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Types: switch :: Monad m => ProcessT m b (c, Event t) -> (t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Types: unsafeExhaust :: (ArrowApply a, Foldable f) => a b (f c) -> ProcessA a b (Event c)
+ Control.Arrow.Machine.Types: unsafeExhaust :: (Monad m, Foldable f) => (b -> m (f c)) -> ProcessT m b (Event c)
- Control.Arrow.Machine.Types: yield :: o -> Plan i o ()
+ Control.Arrow.Machine.Types: yield :: MonadYield m a => a -> m ()
- Control.Arrow.Machine.Utils: accum :: ArrowApply a => b -> ProcessA a (Event (b -> b)) b
+ Control.Arrow.Machine.Utils: accum :: Monad m => b -> ProcessT m (Event (b -> b)) b
- Control.Arrow.Machine.Utils: blocking :: ArrowApply a => ProcessA a (Event ()) (Event c) -> ProcessA a () (Event c)
+ Control.Arrow.Machine.Utils: blocking :: Monad m => ProcessT m (Event ()) (Event a) -> ProcessT m ZeroEvent (Event a)
- Control.Arrow.Machine.Utils: blockingSource :: (ArrowApply a, Foldable f) => f c -> ProcessA a () (Event c)
+ Control.Arrow.Machine.Utils: blockingSource :: (Monad m, Foldable f) => f a -> ProcessT m ZeroEvent (Event a)
- Control.Arrow.Machine.Utils: dAccum :: ArrowApply a => b -> ProcessA a (Event (b -> b)) b
+ Control.Arrow.Machine.Utils: dAccum :: Monad m => b -> ProcessT m (Event (b -> b)) b
- Control.Arrow.Machine.Utils: dHold :: ArrowApply a => b -> ProcessA a (Event b) b
+ Control.Arrow.Machine.Utils: dHold :: Monad m => b -> ProcessT m (Event b) b
- Control.Arrow.Machine.Utils: dSwitch :: ArrowApply a => ProcessA a b (c, Event t) -> (t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Utils: dSwitch :: Monad m => ProcessT m b (c, Event t) -> (t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Utils: dkSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, c) (Event t) -> (ProcessA a b c -> t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Utils: dkSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, c) (Event t) -> (ProcessT m b c -> t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Utils: drSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, Event (ProcessA a b c)) c
+ Control.Arrow.Machine.Utils: drSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, Event (ProcessT m b c)) c
- Control.Arrow.Machine.Utils: edge :: (ArrowApply a, Eq b) => ProcessA a b (Event b)
+ Control.Arrow.Machine.Utils: edge :: (Monad m, Eq b) => ProcessT m b (Event b)
- Control.Arrow.Machine.Utils: fork :: (ArrowApply a, Foldable f) => ProcessA a (Event (f b)) (Event b)
+ Control.Arrow.Machine.Utils: fork :: (Monad m, Foldable f) => ProcessT m (Event (f b)) (Event b)
- Control.Arrow.Machine.Utils: gather :: (ArrowApply a, Foldable f) => ProcessA a (f (Event b)) (Event b)
+ Control.Arrow.Machine.Utils: gather :: (Monad m, Foldable f) => ProcessT m (f (Event b)) (Event b)
- Control.Arrow.Machine.Utils: hold :: ArrowApply a => b -> ProcessA a (Event b) b
+ Control.Arrow.Machine.Utils: hold :: Monad m => b -> ProcessT m (Event b) b
- Control.Arrow.Machine.Utils: interleave :: ArrowApply a => ProcessA a () (Event c) -> ProcessA a (Event b) (Event c)
+ Control.Arrow.Machine.Utils: interleave :: Monad m => ProcessT m ZeroEvent (Event a) -> ProcessT m (Event i) (Event a)
- Control.Arrow.Machine.Utils: kSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, c) (Event t) -> (ProcessA a b c -> t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Utils: kSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, c) (Event t) -> (ProcessT m b c -> t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Utils: now :: ArrowApply a => ProcessA a b (Event ())
+ Control.Arrow.Machine.Utils: now :: Monad m => ProcessT m b (Event ())
- Control.Arrow.Machine.Utils: onEnd :: (ArrowApply a, Occasional' b) => ProcessA a b (Event ())
+ Control.Arrow.Machine.Utils: onEnd :: (Monad m, Occasional' b) => ProcessT m b (Event ())
- Control.Arrow.Machine.Utils: oneshot :: ArrowApply a => c -> ProcessA a b (Event c)
+ Control.Arrow.Machine.Utils: oneshot :: Monad m => c -> ProcessT m b (Event c)
- Control.Arrow.Machine.Utils: pSwitch :: (ArrowApply a, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessA a ext c) -> ProcessA a (b, col c) (Event mng) -> (col (ProcessA a ext c) -> mng -> ProcessA a b (col c)) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Utils: pSwitch :: (Monad m, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessT m ext c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m ext c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c)
- Control.Arrow.Machine.Utils: pSwitchB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a (b, col c) (Event mng) -> (col (ProcessA a b c) -> mng -> ProcessA a b (col c)) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Utils: pSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m b c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c)
- Control.Arrow.Machine.Utils: par :: (ArrowApply a, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessA a ext c) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Utils: par :: (Monad m, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessT m ext c) -> ProcessT m b (col c)
- Control.Arrow.Machine.Utils: parB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a b (col c)
+ Control.Arrow.Machine.Utils: parB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m b (col c)
- Control.Arrow.Machine.Utils: rSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, Event (ProcessA a b c)) c
+ Control.Arrow.Machine.Utils: rSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, Event (ProcessT m b c)) c
- Control.Arrow.Machine.Utils: rpSwitch :: (ArrowApply a, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessA a ext c) -> ProcessA a (b, Event (col (ProcessA a ext c) -> col (ProcessA a ext c))) (col c)
+ Control.Arrow.Machine.Utils: rpSwitch :: (Monad m, Traversable col) => (forall sf. (b -> col sf -> col (ext, sf))) -> col (ProcessT m ext c) -> ProcessT m (b, Event (col (ProcessT m ext c) -> col (ProcessT m ext c))) (col c)
- Control.Arrow.Machine.Utils: rpSwitchB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a (b, Event (col (ProcessA a b c) -> col (ProcessA a b c))) (col c)
+ Control.Arrow.Machine.Utils: rpSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, Event (col (ProcessT m b c) -> col (ProcessT m b c))) (col c)
- Control.Arrow.Machine.Utils: source :: (ArrowApply a, Foldable f) => f c -> ProcessA a (Event b) (Event c)
+ Control.Arrow.Machine.Utils: source :: (Monad m, Foldable f) => f a -> ProcessT m (Event i) (Event a)
- Control.Arrow.Machine.Utils: switch :: ArrowApply a => ProcessA a b (c, Event t) -> (t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Utils: switch :: Monad m => ProcessT m b (c, Event t) -> (t -> ProcessT m b c) -> ProcessT m b c
- Control.Arrow.Machine.Utils: tee :: ArrowApply a => ProcessA a (Event b1, Event b2) (Event (Either b1 b2))
+ Control.Arrow.Machine.Utils: tee :: Monad m => ProcessT m (Event b1, Event b2) (Event (Either b1 b2))

Files

CHANGELOG.md view
@@ -1,4 +1,29 @@ +4.0.0+----------+### Breaking changes of APIs+* Side-effects are represented by `Monad`s rather than `ArrowApply`ies.+    * Replace the base arrow `ProcessA` with `ProcessT`+    * `ProcessA` is now type alias for compatibility+    * Change the signatures of construction functions+        * `constructT`, `repeatedlyT`+        * `construct`, `repeatedly`+    * Change the signatures of running functions+        * `runT`, `runT_`, `run`, `run_`+        * `stepRun`, `stepYield`+            * Delete `ExecInfo`.+* Change the `Occasional'` type class+    * Add method `burst`+    * Move `noEvent` `end` out of the type class+* Delete `echo`. Use `id` instead.++### Additions+* Add `ZeroEvent`. Change the signatures of blocking sources with it.+* Add `Evolution`+* Add type classes `MonadAwait`, `MonadYield`, `MonadStop`+    * Generalize `await`, `yield`, and `stop` to `Evolution`+* Add `fire`, `fire0`+ 3.3.2 ---------- * Modify again the versions of depending packages.
machinecell.cabal view
@@ -1,5 +1,5 @@ name:                machinecell-version:             3.3.2+version:             4.0.0 synopsis:            Arrow based stream transducers license:             BSD3 license-file:        LICENSE@@ -35,27 +35,44 @@         Control.Arrow.Machine,         Control.Arrow.Machine.Types,         Control.Arrow.Machine.Utils,+        Control.Arrow.Machine.Evolution,         Control.Arrow.Machine.ArrowUtil,         Control.Arrow.Machine.Misc.Exception,         Control.Arrow.Machine.Misc.Pump,         Control.Arrow.Machine.Misc.Discrete   other-extensions:    FlexibleInstances, Arrows, RankNTypes, TypeSynonymInstances, MultiParamTypeClasses, GADTs, FlexibleContexts, NoMonomorphismRestriction, RecursiveDo   ghc-options: -Wall-  build-depends:       base >=4.6.0.0 && <5.0, mtl >=2.2 && < 3.0, free >= 4.12 && < 5.0, semigroups >=0.8.3.1 && < 1.0, profunctors >=4.0.4 && <6.0, transformers >= 0.4 && <0.6+  build-depends:       base >=4.7.0.0 && <5.0, mtl >=2.2.1 && <3, free >=4.12.3 && <5, semigroups >=0.18.1 && <1, profunctors >=5.2 && <6, transformers >=0.5.0.0 && <1   hs-source-dirs:      src   default-language:    Haskell2010    if flag(arrow-tr)-    build-depends:    arrows >=0.4.3.0+    build-depends:    arrows >=0.2  Test-suite spec   type:                exitcode-stdio-1.0   default-language:    Haskell2010   hs-source-dirs:      test-  main-is:             spec.hs-  other-modules:       RandomProc, LoopUtil-  Build-depends:       base >=4.0 && <5.0, mtl >=2.2, profunctors >=4.0.4, QuickCheck >=1.0, hspec >=0.2.0, semigroups >=0.8.3.1, machinecell >=1.0.0+  main-is:             Spec.hs+  other-modules:       Common.RandomProc,+                       Types.BasicSpec,+                       Types.ChoiceSpec,+                       Types.LoopSpec,+                       Types.PlanSpec,+                       Types.RuleSpec,+                       Types.SwitchSpec,+                       Types.StepExecutionSpec,+                       Utils.SourceSpec,+                       Misc.PumpSpec+  Build-depends:       base >=4.0 && <5.0, mtl >=2.2.1, profunctors >=5.2, QuickCheck >=1.0, hspec >=0.2.0, semigroups >=0.18.1, machinecell +Test-suite doctest+  type:                exitcode-stdio-1.0+  default-language:    Haskell2010+  hs-source-dirs:      test+  main-is:             doctest.hs+  Build-depends:       base >=4.0 && <5.0, doctest >=0.3.0+ source-repository head   type:		git   location:	https://github.com/as-capabl/machinecell.git@@ -64,4 +81,4 @@ source-repository this   type:		git   location:	https://github.com/as-capabl/machinecell.git-  tag:		release-3.3.2+  tag:		release-4.0.0
src/Control/Arrow/Machine.hs view
@@ -29,80 +29,80 @@         -- They are all designed to import qualified.         module Control.Arrow.Machine.ArrowUtil,         module Control.Arrow.Machine.Types,+        module Control.Arrow.Machine.Evolution,         module Control.Arrow.Machine.Utils        ) where  import Control.Arrow.Machine.ArrowUtil import Control.Arrow.Machine.Types+import Control.Arrow.Machine.Evolution import Control.Arrow.Machine.Utils +-- $setup+-- >>> :set -XArrows+-- >>> import Control.Arrow+-- >>> import Control.Monad.Trans+ -- $introduction -- As other iteratee or pipe libraries, machinecell abstracts general iteration processes. -- -- Here is an example that is a simple iteration over a list. -- -- >>> run (evMap (+1)) [1, 2, 3]--- [2, 3, 4]+-- [2,3,4] ----- In above statement, "`evMap` (+1)" has a type "ProcessA (-\>) (Event Int) (Event Int)",+-- In above statement, "`evMap` (+1)" has a type __"ProcessT Identity (Event Int) (Event Int)"__ , -- which denotes "A stream transducer that takes a series of Int as input,--- gives a series of Int as output, run on base arrow (-\>)."+-- gives a series of Int as output, run on base monad `Identity`." ----- `ProcessA` is the transducer type of machinecell library.+-- `ProcessT` is the transducer type of machinecell library. -- -- = Side effects ----- In general, `Arrow` types other than (-\>) may have side effects.--- For example any monadic side effects can be performed by wrapping the monad with `Kleisli`.+-- The first type argurment of `ProcessT` is the underlying monad.+-- Transtucers can have side effects of the type. ----- ProcessA can run the effects as following.+-- ProcessT can run the effects as following. ----- >>> runKleisli (run_ $ anytime (Kleisli print)) [1, 2, 3]+-- >>> runT_ (fire print) [1, 2, 3] -- 1 -- 2 -- 3 -----  Where `anytime` makes a transducer that executes side effects for each input.--- `run_` is almost same as `run` but discards transducer's output.+--  Where `fire` makes a transducer that executes side effects for each input.+-- `runT_` is almost same as `run` but discards transducer's output. -- -- That is useful in the case rather side effects are main concern. ----- = ProcessA as pipes+-- = ProcessT as pipes ----- "ProcessA a (Event b) (Event c)" transducers are actually one-directional composable pipes.+-- "ProcessT a (Event b) (Event c)" transducers are actually one-directional composable pipes. -- -- They can be constructed from the `Plan` monad. -- In `Plan` monad context, `await` and `yield` can be used to get and emit values. -- And actions of base monads can be `lift`ed to the context. ----- @--- source :: ProcessA (Kleisli IO) (Event ()) (Event String)--- source = repeatedlyT kleisli0 $---   do---     _ \<- await---     x \<- lift getLine---     yield x------ pipe :: ArrowApply a =\> ProcessA a (Event String) (Event String)--- pipe = construct $---   do---     s1 \<- await---     s2 \<- await---     yield (s1 ++ s2)------ sink :: ProcessA (Kleisli IO) (Event String) (Event Void)--- sink = repeatedlyT kleisli0---   do---     x \<- await---     lift $ putStrLn x--- @--- -- Then, resulting processes are composed as `Category` using `(\>\>\>)` operator. ----- > runKleisli (run_ $ source >>> pipe >>> sink) (repeat ())------ This reads two lines from stdin, puts a concatenated line to stdout and finishes.+-- >>> :{+-- let mySource = repeatedly $+--       do+--         _ <- await+--         yield 1+--     myPipe = construct $+--       do+--         s1 <- await+--         s2 <- await+--         yield (s1 + s2)+--     mySink = repeatedlyT $+--       do+--         x <- await+--         lift $ print x+--   in+--     runT_ (mySource >>> myPipe >>> mySink) (repeat ())+-- :}+-- 2 -- -- Unlike other pipe libraries, even the source calls `await`. -- The source awaits dummy input, namely "(repeat ())", and discard input values.@@ -137,25 +137,24 @@ -- -- One of the most attractive feature of machinecell is the /arrow composition/. ----- In addition to `Category`, ProcessA has `Arrow` instance declaration,+-- In addition to `Category`, ProcessT has `Arrow` instance declaration, -- which allows parallel compositions. -- -- If a type has an `Arrow` instance, it can be wrote by ghc extended proc-do notation as following. ----- @--- f :: ProcessA (Kleisli IO) (Event Int) (Event ())--- f = proc x -\>---   do---     -- Process odd integers.---     odds \<- filter $ arr odd -\< x---     anytime $ Kleisli (putStrLn . ("Odd: " ++)) -\< show \<$\> odds------     -- Process even integers.---     evens \<- filter $ arr even -\< x---     anytime $ Kleisli (putStrLn . ("Even: " ++)) -\< show \<$\> evens--- @------ >>> P.runKleisli (run f) [1..10]+-- >>> :{+-- let f :: ProcessT IO (Event Int) (Event ())+--     f = proc x ->+--       do+--         -- Process odd integers.+--         odds <- filterEvent odd -< x+--         fire (putStrLn . ("Odd: " ++)) -< show <$> odds+--         -- Process even integers.+--         evens <- filterEvent even -< x+--         fire (putStrLn . ("Even: " ++)) -< show <$> evens+--   in+--     runT_ f [1..10]+-- :} -- Odd: 1 -- Even: 2 -- Odd: 3@@ -173,8 +172,8 @@ -- But several built-in transducers provide non-event values like below. -- -- @--- hold :: ArrowApply a =\> b -\> ProcessA a (Event b) b--- accum :: ArrowApply a =\> b -\> ProcessA a (Event (b-\>b)) b+-- hold :: ArrowApply a =\> b -\> ProcessT a (Event b) b+-- accum :: ArrowApply a =\> b -\> ProcessT a (Event (b-\>b)) b -- @ -- -- `hold` keeps the last input until a new value is provided.@@ -195,16 +194,15 @@ -- -- An example is below. ----- @--- f :: ArrowApply a =\> ProcessA a (Event Int) (Event Int)--- f = proc x -\>---    do---      y \<- accum 0 -\< (+) \<$\> x---      returnA -\< y \<$ x--- @------ >>> run f [1, 2, 3]--- [1, 3, 6]+-- >>> :{+-- let f = proc x ->+--       do+--         y <- accum 0 -< (+) <$> x+--         returnA -< y <$ x+--   in+--     run f [1, 2, 3]+-- :}+-- [1,3,6] -- -- `(\<$)` operator discards the value of rhs and only uses that's container structure -- e.g. 1 \<$ Just "a" =\> Just 1, 1 \<$ Nothing =\> Nothing,@@ -216,9 +214,9 @@   -- $note--- = Purity of `ProcessA (-\>)`--- Since the 1st type parameter of `ProcessA` represents base monad(ArrowApply),--- "ProcessA (-\>)" is expected to be pure.+-- = Purity of `ProcessT (-\>)`+-- Since the 1st type parameter of `ProcessT` represents base monad(ArrowApply),+-- "ProcessT (-\>)" is expected to be pure. -- -- In other words, the following arrow results the same result for arbitrary f. --@@ -255,26 +253,24 @@ -- -- = Looping ----- Although `ProcessA` is an instance of `ArrowLoop`,+-- Although `ProcessT` is an instance of `ArrowLoop`, -- there is a large limitation. -- -- The limitation is, Events mustn't be looped back to upstream. -- -- In example below, result is [0, 0, 0, 0], not [1, 2, 3, 4]. ----- @--- f = proc x -\>---   do---     rec---         b \<- hold 0 -\< y---         y \<- fork -\< (\xx -\> [xx, xx+1, xx+2, xx+3]) \<$\> x---     returnA -\< b \<$ y------ dHold i = proc x -\> drSwitch (pure i) -\< ((), pure \<$\> x)--- @------ >>> run f [1]--- [0, 0, 0, 0]+-- >>> :{+-- let f = proc x ->+--       do+--         rec+--             b <- hold 0 -< y+--             y <- fork -< (\xx -> [xx, xx+1, xx+2, xx+3]) <$> x+--         returnA -< b <$ y+--   in+--     run f [1]+-- :}+-- [0,0,0,0] -- -- In general, `Event` values refered at upstream in rec statements are -- almost always `NoEvent`s.
+ src/Control/Arrow/Machine/Evolution.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE Safe #-}+{-# LANGUAGE Arrows #-}++module+    Control.Arrow.Machine.Evolution+      (+        switchAfter,+        dSwitchAfter,+        kSwitchAfter,+        dkSwitchAfter,+        gSwitchAfter,+        dgSwitchAfter,+        finishWith,+        evolve+      )+where++import Prelude hiding (id, (.))+import Data.Void+import Control.Category+import Control.Arrow.Machine.Types+import Control.Monad.Cont (cont, runCont)++{-# INLINE switchAfter #-}+switchAfter ::+    Monad m =>+    ProcessT m i (o, Event r) ->+    Evolution i o m r+switchAfter pf = Evolution $ cont $ switch pf++{-# INLINE dSwitchAfter #-}+dSwitchAfter ::+    Monad m =>+    ProcessT m i (o, Event r) ->+    Evolution i o m r+dSwitchAfter pf = Evolution $ cont $ dSwitch pf++{-# INLINE kSwitchAfter #-}+kSwitchAfter ::+    Monad m =>+    ProcessT m (i, o) (Event r) ->+    ProcessT m i o ->+    Evolution i o m (ProcessT m i o, r)+kSwitchAfter test pf = Evolution $ cont $ kSwitch pf test . curry++{-# INLINE dkSwitchAfter #-}+dkSwitchAfter ::+    Monad m =>+    ProcessT m (i, o) (Event r) ->+    ProcessT m i o ->+    Evolution i o m (ProcessT m i o, r)+dkSwitchAfter test pf = Evolution $ cont $ dkSwitch pf test . curry++{-# INLINE gSwitchAfter #-}+gSwitchAfter ::+    Monad m =>+    ProcessT m i (p, r) ->+    ProcessT m (q, r) (o, Event t) ->+    ProcessT m p q ->+    Evolution i o m (ProcessT m p q, t)+gSwitchAfter pre post pf = Evolution $ cont $ gSwitch pre pf post . curry++{-# INLINE dgSwitchAfter #-}+dgSwitchAfter ::+    Monad m =>+    ProcessT m i (p, r) ->+    ProcessT m (q, r) (o, Event t) ->+    ProcessT m p q ->+    Evolution i o m (ProcessT m p q, t)+dgSwitchAfter pre post pf = Evolution $ cont $ dgSwitch pre pf post . curry++{-# INLINE finishWith #-}+finishWith ::+    Monad m =>+    ProcessT m i o ->+    Evolution i o m r+finishWith pf = Evolution $ cont $ const pf++{-# INLINE evolve #-}+evolve ::+    Evolution i o m Void ->+    ProcessT m i o+evolve ev = runCont (runEvolution ev) absurd
src/Control/Arrow/Machine/Misc/Discrete.hs view
@@ -57,8 +57,8 @@ finite number of changing points.  >>> import qualified Control.Arrow.Machine.Misc.Discrete as D->>> run (D.hold "apple" >>> D.arr reverse >>> D.edge) ["orange", "grape"]-["elppa", "egnaro", "eparg"]+>>> P.run (D.hold "apple" >>> D.arr reverse >>> D.edge) ["orange", "grape"]+["elppa","egnaro","eparg"]  In above example, input data of "reverse" is continuous. But the "D.edge" transducer extracts changing points without calling string comparison.@@ -74,15 +74,15 @@   }  makeT ::-    ArrowApply a =>-    P.ProcessA a (P.Event (), b) (T b)+    Monad m =>+    P.ProcessT m (P.Event (), b) (T b) makeT = Arr.arr $ uncurry T   stimulate ::-    ArrowApply a =>-    P.ProcessA a b (T c) ->-    P.ProcessA a b (T c)+    Monad m =>+    P.ProcessT m b (T c) ->+    P.ProcessT m b (T c) stimulate sf = P.dgSwitch (id &&& id) sf body $ \sf' _ -> sf'   where     body = proc (dy, _) ->@@ -92,117 +92,117 @@         returnA -< (disc, updates disc)  arr ::-    ArrowApply a =>+    Monad m =>     (b->c) ->-    P.ProcessA a (T b) (T c)+    P.ProcessT m (T b) (T c) arr f =     Arr.arr $ \(T ev x) ->         T ev (f x)  arr2 ::-    ArrowApply a =>+    Monad m =>     (b1->b2->c) ->-    P.ProcessA a (T b1, T b2) (T c)+    P.ProcessT m (T b1, T b2) (T c) arr2 f =     Arr.arr $ \(T ev1 x1, T ev2 x2) ->         T (mconcat [ev1, ev2]) (f x1 x2)  arr3 ::-    ArrowApply a =>+    Monad m =>     (b1->b2->b3->c) ->-    P.ProcessA a (T b1, T b2, T b3) (T c)+    P.ProcessT m (T b1, T b2, T b3) (T c) arr3 f =     Arr.arr $ \(T ev1 x1, T ev2 x2, T ev3 x3) ->         T (mconcat [ev1, ev2, ev3]) (f x1 x2 x3)  arr4 ::-    ArrowApply a =>+    Monad m =>     (b1->b2->b3->b4->c) ->-    P.ProcessA a (T b1, T b2, T b3, T b4) (T c)+    P.ProcessT m (T b1, T b2, T b3, T b4) (T c) arr4 f =     Arr.arr $ \(T ev1 x1, T ev2 x2, T ev3 x3, T ev4 x4) ->         T (mconcat [ev1, ev2, ev3, ev4]) (f x1 x2 x3 x4)  arr5 ::-    ArrowApply a =>+    Monad m =>     (b1->b2->b3->b4->b5->c) ->-    P.ProcessA a (T b1, T b2, T b3, T b4, T b5) (T c)+    P.ProcessT m (T b1, T b2, T b3, T b4, T b5) (T c) arr5 f =     Arr.arr $ \(T ev1 x1, T ev2 x2, T ev3 x3, T ev4 x4, T ev5 x5) ->         T (mconcat [ev1, ev2, ev3, ev4, ev5]) (f x1 x2 x3 x4 x5)  constant::-    ArrowApply a =>+    Monad m =>     c ->-    P.ProcessA a b (T c)+    P.ProcessT m b (T c) constant x =     (P.now &&& Arr.arr (const x)) >>> makeT  -- |Constant without initial notifications. -- Users must manage initialization manually. unsafeConstant::-    ArrowApply a =>+    Monad m =>     c ->-    P.ProcessA a b (T c)+    P.ProcessT m b (T c) unsafeConstant x =     (pure P.noEvent &&& Arr.arr (const x)) >>> makeT  onUpdate ::-    ArrowApply a =>-    P.ProcessA a (P.Event b) (P.Event ())+    Monad m =>+    P.ProcessT m (P.Event b) (P.Event ()) onUpdate = proc ev ->   do     n <- P.now -< ()     returnA -< n `mappend` P.collapse ev  hold ::-    ArrowApply a =>+    Monad m =>     b ->-    P.ProcessA a (P.Event b) (T b)+    P.ProcessT m (P.Event b) (T b) hold i =     (onUpdate &&& P.hold i) >>> makeT  accum ::-    ArrowApply a =>+    Monad m =>     b ->-    P.ProcessA a (P.Event (b->b)) (T b)+    P.ProcessT m (P.Event (b->b)) (T b) accum i =     (onUpdate &&& P.accum i) >>> makeT  fromEq ::-    (ArrowApply a, Eq b) =>-    P.ProcessA a b (T b)+    (Monad m, Eq b) =>+    P.ProcessT m b (T b) fromEq = proc x ->   do     ev <- P.edge -< x     returnA -< T (P.collapse ev) x  edge ::-    ArrowApply a =>-    P.ProcessA a (T b) (P.Event b)+    Monad m =>+    P.ProcessT m (T b) (P.Event b) edge = Arr.arr $ \(T ev x) -> x <$ ev  asUpdater ::-    ArrowApply a =>-    a b c ->-    P.ProcessA a (T b) (P.Event c)-asUpdater ar = edge >>> P.anytime ar+    Monad m =>+    (b -> m c) ->+    P.ProcessT m (T b) (P.Event c)+asUpdater fmx = edge >>> P.fire fmx   kSwitch ::-    ArrowApply a =>-    P.ProcessA a b (T c) ->-    P.ProcessA a (b, T c) (P.Event t) ->-    (P.ProcessA a b (T c) -> t -> P.ProcessA a b (T c)) ->-    P.ProcessA a b (T c)+    Monad m =>+    P.ProcessT m b (T c) ->+    P.ProcessT m (b, T c) (P.Event t) ->+    (P.ProcessT m b (T c) -> t -> P.ProcessT m b (T c)) ->+    P.ProcessT m b (T c) kSwitch sf test k = P.kSwitch sf test (\sf' x -> stimulate (k sf' x))  dkSwitch ::-    ArrowApply a =>-    P.ProcessA a b (T c) ->-    P.ProcessA a (b, T c) (P.Event t) ->-    (P.ProcessA a b (T c) -> t -> P.ProcessA a b (T c)) ->-    P.ProcessA a b (T c)+    Monad m =>+    P.ProcessT m b (T c) ->+    P.ProcessT m (b, T c) (P.Event t) ->+    (P.ProcessT m b (T c) -> t -> P.ProcessT m b (T c)) ->+    P.ProcessT m b (T c) dkSwitch sf test k = P.dkSwitch sf test (\sf' x -> stimulate (k sf' x))  @@ -213,8 +213,8 @@  @ holdAdd ::-    (ArrowApply a, Num b) =>-    ProcessA a (Event b, Event b) (Discrete b)+    (Monad m, Num b) =>+    ProcessT m (Event b, Event b) (Discrete b) holdAdd = proc (evx, evy) ->   do     x <- D.hold 0 -< evx@@ -228,28 +228,28 @@ -}  -- |Discrete algebra type.-newtype Alg a i o =-    Alg { eval :: P.ProcessA a i (T o) }+newtype Alg m i o =+    Alg { eval :: P.ProcessT m i (T o) }  refer ::-    ArrowApply a =>-    (e -> T b) -> Alg a e b+    Monad m =>+    (e -> T b) -> Alg m e b refer = Alg . Arr.arr  instance-    ArrowApply a => Functor (Alg a i)+    Monad m => Functor (Alg m i)   where     fmap f alg = Alg $ eval alg >>> arr f  instance-    ArrowApply a => Applicative (Alg a i)+    Monad m => Applicative (Alg m i)   where     pure = Alg . constant     af <*> aa = Alg $ (eval af &&& eval aa) >>> arr2 ($)  instance-    (ArrowApply a, Num o) =>-    Num (Alg a i o)+    (Monad m, Num o) =>+    Num (Alg m i o)   where     abs = fmap abs     signum = fmap signum
src/Control/Arrow/Machine/Misc/Pump.hs view
@@ -34,16 +34,16 @@ newtype Duct a = Duct (Endo [a])  oneMore ::-    ArrowApply a =>-    P.ProcessA a (P.Event ()) (P.Event ())+    Monad m =>+    P.ProcessT m (P.Event ()) (P.Event ()) oneMore = proc ev ->   do     ed <- P.onEnd -< ev     P.gather -< [ev, ed]      intake ::-    ArrowApply a =>-    P.ProcessA a (P.Event b, P.Event ()) (Duct b)+    Monad m =>+    P.ProcessT m (P.Event b, P.Event ()) (Duct b) intake = proc (ev, clock) ->   do     cl2 <- oneMore -< clock@@ -52,8 +52,8 @@     returnA -< Duct e  outlet ::-    ArrowApply a =>-    P.ProcessA a (Duct b, P.Event ()) (P.Event b)+    Monad m =>+    P.ProcessT m (Duct b, P.Event ()) (P.Event b) outlet = proc (~(Duct dct), clock) ->   do     cl2 <- oneMore -< clock
src/Control/Arrow/Machine/Types.hs view
@@ -6,1445 +6,1647 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-}--module-    Control.Arrow.Machine.Types-      (-        -- * Stream transducer type-        ProcessA(),--        -- * Event type and utility-        Occasional' (..),-        Occasional (..),-        Event (),-        condEvent,-        filterEvent,-        filterJust,-        filterLeft,-        filterRight,-        splitEvent,-        evMap,--        -- * Coroutine monad-        -- | Procedural coroutine monad that can await or yield values.-        ---        -- Coroutines can be encoded to machines by `constructT` or so on and-        -- then put into `ProcessA` compositions.-        PlanT(..),-        Plan,--        await,-        yield,-        stop,-        catchP,--        stopped,-        muted,--        -- * Constructing machines from plans-        constructT,-        repeatedlyT,--        construct,-        repeatedly,--        -- * Running machines (at once)-        run,-        runOn,-        run_,--        -- * Running machines (step-by-step)-        ExecInfo(..),-        stepRun,-        stepYield,--        -- * Primitive machines - switches-        -- | Switches inspired by Yampa library.-        -- Signature is almost same, but collection requirement is  not only 'Functor',-        -- but 'Tv.Traversable'. This is because of side effects.-        switch,-        dSwitch,-        rSwitch,-        drSwitch,-        kSwitch,-        dkSwitch,-        gSwitch,-        dgSwitch,-        pSwitch,-        pSwitchB,-        dpSwitch,-        dpSwitchB,-        rpSwitch,-        rpSwitchB,-        drpSwitch,-        drpSwitchB,-        par,-        parB,--        -- * Primitive machines - other safe primitives-        fit,-        fitW,--        -- * Primitive machines - unsafe-        unsafeExhaust,-      )-where--import qualified Control.Category as Cat-import Data.Profunctor (Profunctor, dimap, rmap)-import Control.Arrow-import Control.Monad-import Control.Monad.Trans-import Control.Monad.State.Strict-import Control.Monad.Reader-import Control.Monad.Writer hiding ((<>))-import Control.Monad.Identity-import Control.Monad.Trans.Cont (ContT(..), evalContT, callCC)-import Control.Applicative-import qualified Data.Foldable as Fd-import Data.Traversable as Tv-import Data.Semigroup (Semigroup, (<>))-import Data.Maybe (fromMaybe, isNothing, isJust)-import qualified Control.Monad.Trans.Free as F-import qualified Control.Monad.Trans.Free.Church as F-import Control.Arrow.Machine.ArrowUtil-import GHC.Exts (build)----- | To get multiple outputs by one input, the `Phase` parameter is introduced.------ Once a value `Feed`ed, the machine is `Sweep`ed until it `Suspend`s.-data Phase = Feed | Sweep | Suspend deriving (Eq, Show)--instance-    Monoid Phase-  where-    mempty = Sweep--    mappend Feed _ = Feed-    mappend _ Feed = Feed-    mappend Suspend _ = Suspend-    mappend _ Suspend = Suspend-    mappend Sweep Sweep = Sweep---type ProcType a b c = ProcessA a b c--class Stepper a b c s | s -> a, s -> b, s -> c-  where-    feed :: s -> a b (c, s)-    sweep :: s -> a b (Maybe c, s)-    suspend :: s -> b -> c---- | The stream transducer arrow.------ To construct `ProcessA` instances, use `Control.Arrow.Machine.Plan.Plan`,--- `arr`, functions declared in `Control.Arrow.Machine.Utils`,--- or arrow combinations of them.------ See an introduction at "Control.Arrow.Machine" documentation.-data ProcessA a b c = ProcessA {-    paFeed :: a b (c, ProcessA a b c),-    paSweep :: a b (Maybe c, ProcessA a b c),-    paSuspend :: !(b -> c)-  }--instance-    Stepper a b c (ProcessA a b c)-  where-    feed = paFeed-    sweep = paSweep-    suspend = paSuspend--toProcessA ::-    (ArrowApply a, Stepper a b c s) =>-    s -> ProcessA a b c-toProcessA s = ProcessA {-    paFeed = feed s >>> arr (second toProcessA),-    paSweep = sweep s >>> arr (second toProcessA),-    paSuspend = suspend s-  }-{-# INLINE[2] toProcessA  #-}---- For internal use-class-    (Applicative f, Monad f) => ProcessHelper f-  where-    step ::-        (ArrowApply a, Stepper a b c s) =>-        s -> a b (f c, s)-    helperToMaybe :: f a -> Maybe a-    weakly :: a -> f a--    compositeStep ::-        (ArrowApply a, Stepper a b p s1, Stepper a p c s2) =>-        s1 -> s2 ->-        a b (f c, s1, s2)---instance-    ProcessHelper Identity-  where-    step pa = feed pa >>> first (arr Identity)-    helperToMaybe = Just . runIdentity-    weakly = Identity-    compositeStep sf test = proc x ->-      do-        (y, sf') <- feed sf -< x-        (z, test') <- feed test -< y-        returnA -< (return z, sf', test')--instance-    ProcessHelper Maybe-  where-    step = sweep-    helperToMaybe = id-    weakly _ = Nothing-    compositeStep sf0 test0 = proc x ->-      do-        let y = suspend sf0 x-        (mt, test') <- sweep test0 -< y-        (case mt of-            Just t -> arr $ const (Just t, sf0, test')-            Nothing -> cont sf0 test')-                -<< x-      where-        cont sf test = proc x ->-          do-            (my, sf') <- sweep sf -< x-            (case my of-                Just y -> cont2 y sf' test-                Nothing -> arr $ const (Nothing, sf', test))-                    -<< x-        cont2 y sf test = proc _ ->-          do-            (t, test') <- feed test -< y-            returnA -< (Just t, sf, test')--makePA ::-    Arrow a =>-    (forall f. ProcessHelper f =>-        a b (f c, ProcessA a b c)) ->-    (b -> c) ->-    ProcessA a b c-makePA h !sus = ProcessA {-    paFeed = h >>> first (arr runIdentity),-    paSweep = h,-    paSuspend = sus-  }---data CompositeStep a b c s1 s2-  where-    CompositeStep ::-        (Stepper a b p s1, Stepper a p c s2) =>-        s1 -> s2 ->-        CompositeStep a b c s1 s2--instance-    ArrowApply a => Stepper a b c (CompositeStep a b c s1 s2)-  where-    feed (CompositeStep s1 s2) =-        compositeStep s1 s2 >>>-            arr (\(fz, s1', s2') -> (runIdentity $ fz, CompositeStep s1' s2'))-    sweep (CompositeStep s1 s2) =-        compositeStep s1 s2 >>>-            arr (\(fz, s1', s2') -> (fz, CompositeStep s1' s2'))-    suspend (CompositeStep s1 s2) =-        suspend s2 . suspend s1---data IDStep a b c-  where-    IDStep :: IDStep (a :: * -> * -> *) b b--instance-    ArrowApply a => Stepper a b c (IDStep a b c)-  where-    feed IDStep = Cat.id &&& arr (const IDStep)-    sweep IDStep = arr (const (Nothing, IDStep))-    suspend IDStep = id--newtype ArrStep (a :: * -> * -> *) b c = ArrStep (b -> c)--instance-    ArrowApply a => Stepper a b c (ArrStep a b c)-  where-    feed (ArrStep f) = arr $ \x -> (f x, ArrStep f)-    sweep (ArrStep f) = arr $ const (Nothing, ArrStep f)-    suspend (ArrStep f) = f---data ParStep a b c s1 s2-  where-    ParStep ::-        (Stepper a b1 c1 s1, Stepper a b2 c2 s2) =>-        s1 -> s2 ->-        ParStep a (b1, b2) (c1, c2) s1 s2--instance-    ArrowApply a => Stepper a b c (ParStep a b c s1 s2)-  where-    feed (ParStep f g) = proc (x1, x2) ->-      do-        (y1, f') <- feed f -< x1-        (y2, g') <- feed g -< x2-        returnA -< ((y1, y2), ParStep f' g')-    sweep (ParStep f g) = proc (x1, x2) ->-      do-        (my1, f') <- sweep f -< x1-        (my2, g') <- sweep g -< x2-        let y1 = fromMaybe (suspend f' x1) my1 -- suspend f ?-            y2 = fromMaybe (suspend g' x2) my2-            r = if (isNothing my1 && isNothing my2) then Nothing else Just (y1, y2)-        returnA -< (r, ParStep f' g')-    suspend (ParStep f g) = suspend f *** suspend g----- |Natural transformation-fit ::-    (ArrowApply a, ArrowApply a') =>-    (forall p q. a p q -> a' p q) ->-    ProcessA a b c -> ProcessA a' b c-fit f pa =-    arr Identity >>>-    fitW runIdentity (\ar -> arr runIdentity >>> f ar) pa---- |Experimental: more general fit.------ Should w be a comonad?-fitW :: (ArrowApply a, ArrowApply a', Functor w) =>-    (forall p. w p -> p) ->-    (forall p q. a p q -> a' (w p) q) -> -    ProcessA a b c -> ProcessA a' (w b) c-fitW extr f pa = makePA-    (f (step pa) >>> arr (second $ fitW extr f))-    (extr >>> suspend pa)---instance-    ArrowApply a => Profunctor (ProcessA a)-  where-    dimap = dimapProc-    {-# INLINE dimap #-}--dimapProc ::-    ArrowApply a =>-    (b->c)->(d->e)->-    ProcType a c d -> ProcType a b e-dimapProc f g pa = makePA-    (arr f >>> step pa >>> (arr (fmap g) *** arr (dimapProc f g)))-    (dimap f g (suspend pa))--{-# NOINLINE dimapProc #-}---instance-    ArrowApply a => Functor (ProcessA a i)-  where-    fmap = rmap--instance-    ArrowApply a => Applicative (ProcessA a i)-  where-    pure = arr . const-    pf <*> px = (pf &&& px) >>> arr (uncurry ($))---instance-    ArrowApply a => Cat.Category (ProcessA a)-  where-    id = idProc-    {-# INLINE id #-}--    g . f = compositeProc f g-    {-# INLINE (.) #-}---instance-    ArrowApply a => Arrow (ProcessA a)-  where-    arr = arrProc-    {-# INLINE arr #-}--    first pa = parProc pa idProc-    {-# INLINE first #-}--    second pa = parProc idProc pa-    {-# INLINE second #-}--    (***) = parProc-    {-# INLINE (***) #-}---parProc :: ArrowApply a =>-    ProcType a b c ->-    ProcType a d e ->-    ProcType a (b, d) (c, e)-parProc f g = toProcessA $ ParStep f g-{-# INLINE [0] parProc #-}--idProc :: ArrowApply a => ProcType a b b-idProc = makePA (arr $ \x -> (weakly x, idProc)) id-{-# NOINLINE idProc #-}--arrProc :: ArrowApply a => (b->c) -> ProcType a b c-arrProc f = makePA (arr $ \x -> (weakly (f x), arrProc f)) f-{-# NOINLINE arrProc #-}---- |Composition is proceeded by the backtracking strategy.-compositeProc :: ArrowApply a =>-              ProcType a b d -> ProcType a d c -> ProcType a b c-compositeProc f0 g0 = ProcessA {-    paFeed = proc x ->-      do-        (y, f') <- feed f0 -< x-        (z, g') <- feed g0 -< y-        returnA -< (z, compositeProc f' g'),-    paSweep = proc x ->-      do-        (mz, g') <- sweep g0 -< suspend f0 x-        (case mz-          of-            Just z -> arr $ const (Just z, compositeProc f0 g')-            Nothing -> btrk f0 g')-                -<< x,-    paSuspend = suspend f0 >>> suspend g0-  }-  where-    btrk f g = proc x ->-      do-        (my, f') <- sweep f -< x-        (mz, g') <--            (case my-              of-                Just y -> proc () ->-                  do-                    (z, g') <- feed g -< y-                    returnA -< (Just z, g')-                Nothing -> proc () ->-                  do-                    returnA -< (Nothing, g))-                -<< ()-        returnA -< (mz, compositeProc f' g')--{-# NOINLINE compositeProc #-}---- rules-{-# RULES-"ProcessA: id/*"-    forall g. compositeProc idProc g = g-"ProcessA: */id"-    forall f. compositeProc f idProc = f--"ProcessA: concat/concat"-    forall f g h. compositeProc (compositeProc f g) h = compositeProc f (compositeProc g h)--"ProcessA: dimap/dimap"-    forall f g h i j. dimapProc f j (dimapProc g i h)  = dimapProc (g . f) (j . i) h-"ProcessA: dimap/arr"-    forall f g h. dimapProc f h (arrProc g) = arrProc (h . g . f)--"ProcessA: arr***/par"-    forall f1 f2 g1 g2 h. compositeProc (parProc f1 (arrProc f2)) (compositeProc (parProc g1 g2) h) =-        compositeProc (parProc (compositeProc f1 g1) (dimapProc f2 id g2)) h-"ProcessA: arr***/par-2"-    forall f1 f2 g1 g2. compositeProc (parProc f1 (arrProc f2)) (parProc g1 g2) =-        parProc (compositeProc f1 g1) (dimapProc f2 id g2)-"ProcessA: par/***arr"-    forall f1 f2 g1 g2 h. compositeProc (parProc f1 f2) (compositeProc (parProc (arrProc g1) g2) h) =-        compositeProc (parProc (dimapProc id g1 f1) (compositeProc f2 g2)) h-"ProcessA: par/***arr-2"-    forall f1 f2 g1 g2. compositeProc (parProc f1 f2) (parProc (arrProc g1) g2) =-        parProc (dimapProc id g1 f1) (compositeProc f2 g2)--"ProcessA: first/par"-    forall f1 g1 g2 h. compositeProc (parProc f1 idProc) (compositeProc (parProc g1 g2) h) =-        compositeProc (parProc (compositeProc f1 g1) g2) h-"ProcessA: first/par-2"-    forall f1 g1 g2. compositeProc (parProc f1 idProc) (parProc g1 g2) =-        parProc (compositeProc f1 g1) g2-"ProcessA: par/second"-    forall f1 f2 g2 h. compositeProc (parProc f1 f2) (compositeProc (parProc idProc g2) h) =-        compositeProc (parProc f1 (compositeProc f2 g2)) h-"ProcessA: par/second-2"-    forall f1 f2 g2. compositeProc (parProc f1 f2) (parProc idProc g2) =-        parProc f1 (compositeProc f2 g2)--"ProcessA: arr/arr"-    forall f g h. compositeProc (arrProc f) (compositeProc (arrProc g) h) =-        compositeProc (arrProc (g . f)) h-"ProcessA: arr/arr-2"-    forall f g. compositeProc (arrProc f) (arrProc g) = arrProc (g . f)-"ProcessA: arr/*" [1]-    forall f g. compositeProc (arrProc f) g = dimapProc f id g-"ProcessA: */arr" [1]-    forall f g. compositeProc f (arrProc g) = dimapProc id g f-"ProcessA: arr***arr" [0]-    forall f g. parProc (arrProc f) (arrProc g) = arrProc (f *** g)-  #-}---instance-    ArrowApply a => ArrowChoice (ProcessA a)-  where-    left pa0 = makePA-        (proc eth -> sweep' pa0 eth -<< ())-        (left $ suspend pa0)-      where-        sweep' pa (Left x) = proc () ->-          do-            (my, pa') <- step pa -< x-            returnA -< (Left <$> my, left pa')-        sweep' pa (Right d) = proc () ->-            returnA -< (weakly (Right d), left pa)--instance-    ArrowApply a => ArrowLoop (ProcessA a)-  where-    loop pa =-        makePA-            (proc x ->-              do-                (hyd, pa') <- step pa -< (x, loopSusD x)-                returnA -< (fst <$> hyd, loop pa'))-            (loop $ suspend pa)-      where-        loopSusD = loop (suspend pa >>> \(_, d) -> (d, d))---- | Discrete events on a time line.--- Created and consumed by various transducers.-data Event a = Event a | NoEvent | End---instance-    Functor Event-  where-    fmap _ NoEvent = NoEvent-    fmap _ End = End-    fmap f (Event x) = Event (f x)---instance-    Semigroup a => Monoid (Event a)-  where-    mempty = End-    Event x `mappend` Event y = Event (x <> y)-    Event x `mappend` _ = Event x-    _ `mappend` Event y = Event y-    NoEvent `mappend` _ = NoEvent-    _ `mappend` NoEvent = NoEvent-    _ `mappend` _ = End------ | Signals that can be absent(`NoEvent`) or end.--- For composite structure, `collapse` can be defined as monoid sum of all member occasionals.-class-    Occasional' a-  where-    collapse :: a -> Event ()---- | Occasional signals with creation methods.-class-    Occasional' a => Occasional a-  where-    noEvent :: a-    end :: a---instance-    (Occasional' a, Occasional' b) => Occasional' (a, b)-  where-    collapse (x, y) = collapse x `mappend` collapse y--instance-    (Occasional a, Occasional b) => Occasional (a, b)-  where-    noEvent = (noEvent, noEvent)-    end = (end, end)--instance-    Occasional' (Event a)-  where-    collapse = (() <$)--instance-    Occasional (Event a)-  where-    noEvent = NoEvent-    end = End---condEvent :: Bool -> Event a -> Event a-condEvent _ End = End-condEvent True ev = ev-condEvent False _ = NoEvent--filterEvent ::-    Arrow ar =>-    (a -> Bool) ->-    ar (Event a) (Event a)-filterEvent cond = filterJust <<< evMap mcond-  where-    mcond x-        | cond x = Just x-        | otherwise = Nothing--filterJust ::-    Arrow ar => ar (Event (Maybe a)) (Event a)-filterJust = arr filterJust'-  where-    filterJust' (Event (Just x)) = Event x-    filterJust' (Event Nothing) = NoEvent-    filterJust' NoEvent = NoEvent-    filterJust' End = End--filterLeft ::-    Arrow ar =>-    ar (Event (Either a b)) (Event a)-filterLeft = filterJust <<< evMap (either Just (const Nothing))--filterRight ::-    Arrow ar =>-    ar (Event (Either a b)) (Event b)-filterRight = filterJust <<< evMap (either (const Nothing) Just)--splitEvent ::-    Arrow ar =>-    ar (Event (Either a b)) (Event a, Event b)-splitEvent = filterLeft &&& filterRight---- | Alias of "arr . fmap"------ While "ProcessA a (Event b) (Event c)" means a transducer from b to c,--- function b->c can be lifted into a transducer by fhis function.------ But in most cases you needn't call this function in proc-do notations,--- because `arr`s are completed automatically while desugaring.------ For example,------ @--- proc x -> returnA -\< f \<$\> x--- @------ is equivalent to------ @--- evMap f--- @-evMap ::  Arrow a => (b->c) -> a (Event b) (Event c)-evMap = arr . fmap---stopped ::-    (ArrowApply a, Occasional c) => ProcessA a b c-stopped = arr (const end)---muted ::-    (ArrowApply a, Occasional' b, Occasional c) => ProcessA a b c-muted = proc x ->-  do-    ed <- construct (forever await `catchP` yield ()) -< collapse x-    rSwitch (arr $ const noEvent) -< ((), stopped <$ ed)----data PlanF i o a where-  AwaitPF :: (i->a) -> a -> PlanF i o a-  YieldPF :: o -> a -> PlanF i o a-  StopPF :: PlanF i o a--instance (Functor (PlanF i o)) where-  fmap g (AwaitPF f ff) = AwaitPF (g . f) (g ff)-  fmap g (YieldPF x r) = YieldPF x (g r)-  fmap _ StopPF = StopPF--newtype PlanT i o m a =-    PlanT { freePlanT :: F.FT (PlanF i o) m a }-  deriving-    (Functor, Applicative, Monad, MonadTrans,-     Alternative)-    -- , MonadError, MonadReader, MonadCatch, MonadThrow, MonadIO, MonadCont-type Plan i o a = forall m. Monad m => PlanT i o m a--instance-    MonadReader r m => MonadReader r (PlanT i o m)-  where-    ask = PlanT ask-    local f (PlanT pl) = PlanT $ local f pl--instance-    MonadWriter w m => MonadWriter w (PlanT i o m)-  where-    tell = PlanT . tell-    listen = PlanT . listen . freePlanT-    pass = PlanT . pass . freePlanT--instance-    MonadState s m => MonadState s (PlanT i o m)-  where-    get = PlanT get-    put = PlanT . put--instance-    (Monad m, Alternative m) => MonadPlus (PlanT i o m)-  where-    mzero = stop-    mplus = catchP--yield :: o -> Plan i o ()-yield x = PlanT . F.liftF $ YieldPF x ()--await :: Plan i o i-await = PlanT $ F.FT $ \pr free -> free id (AwaitPF pr (free pr StopPF))--stop :: Plan i o a-stop = PlanT $ F.liftF $ StopPF---catchP:: Monad m =>-    PlanT i o m a -> PlanT i o m a -> PlanT i o m a--catchP (PlanT pl) cont0 =-    PlanT $ F.FT $ \pr free ->-        F.runFT-            pl-            (pr' pr)-            (free' cont0 pr free)-  where-    pr' pr = pr--    free' ::-        Monad m =>-        PlanT i o m a ->-        (a -> m r) ->-        (forall x. (x -> m r) -> PlanF i o x -> m r) ->-        (y -> m r) ->-        (PlanF i o y) ->-        m r-    free' (PlanT cont) pr free _ StopPF =-        F.runFT cont pr free-    free' (PlanT cont) pr free r (AwaitPF f ff) =-        free-            (either (\_ -> F.runFT cont pr free) r)-            (AwaitPF (Right . f) (Left ff))-    free' _ _ free r pf =-        free r pf-----constructT ::-    (Monad m, ArrowApply a) =>-    (forall b. m b -> a () b) ->-    PlanT i o m r ->-    ProcessA a (Event i) (Event o)-constructT = constructT'---constructT' ::-    forall a m i o r.-    (Monad m, ArrowApply a) =>-    (forall b. m b -> a () b) ->-    PlanT i o m r ->-    ProcessA a (Event i) (Event o)-constructT' fit0 (PlanT pl0) = prependProc $ F.runFT pl0 pr free-  where-    fit' :: (b -> m c) -> a b c-    fit' fmy = proc x -> fit0 (fmy x) -<< ()--    prependProc ::-        m (Event o, ProcessA a (Event i) (Event o)) ->-        ProcessA a (Event i) (Event o)-    prependProc mr = ProcessA {-        paFeed = proc ex -> do { r <- fit0 mr -< (); prependFeed r -<< ex} ,-        paSweep = proc ex -> do { r <- fit0 mr -< (); prependSweep r -<< ex},-        paSuspend = const NoEvent-      }--    prependFeed (Event x, pa) = arr $ const (Event x, pa)-    prependFeed (NoEvent, pa) = feed pa-    prependFeed (End, _) = arr $ const (End, stopped)--    prependSweep (Event x, pa) = arr $ const (Just (Event x), pa)-    prependSweep (NoEvent, pa) = sweep pa-    prependSweep (End, _) = arr $ const (Just End, stopped)--    pr _ = return (End, stopped)--    free ::-        (x -> m (Event o, ProcessA a (Event i) (Event o)))->-        PlanF i o x ->-        m (Event o, ProcessA a (Event i) (Event o))-    free r (YieldPF y cont) =-        return (Event y, prependProc (r cont))-    free r pl@(AwaitPF f ff) =-        return (NoEvent, awaitProc fma)-      where-        fma (Event x) = r (f x)-        fma NoEvent = free r pl-        fma End = r ff-    free _ StopPF =-        return (End, stopped)--    awaitProc fma = ProcessA {-        paFeed = fit' fma,-        paSweep = fit' fma >>> first eToM,-        paSuspend = const NoEvent-      }--    eToM :: a (Event b) (Maybe (Event b))-    eToM = arr eToMpure-    eToMpure NoEvent = Nothing-    eToMpure e = Just e---repeatedlyT :: (Monad m, ArrowApply a) =>-              (forall b. m b -> a () b) ->-              PlanT i o m r ->-              ProcessA a (Event i) (Event o)--repeatedlyT f = constructT f . forever----- for pure-construct :: ArrowApply a =>-             PlanT i o Identity r ->-             ProcessA a (Event i) (Event o)-construct = constructT (arr . const . runIdentity)--repeatedly :: ArrowApply a =>-              PlanT i o Identity r ->-              ProcessA a (Event i) (Event o)-repeatedly = construct . forever-------- Switches----switch ::-    ArrowApply a =>-    ProcessA a b (c, Event t) ->-    (t -> ProcessA a b c) ->-    ProcessA a b c-switch sf k = ggSwitch (const ()) sf (\() -> k)---dSwitch ::-    ArrowApply a =>-    ProcessA a b (c, Event t) ->-    (t -> ProcessA a b c) ->-    ProcessA a b c-dSwitch sf k = dggSwitch (const ()) sf (\() -> k)---rSwitch ::-    ArrowApply a => ProcessA a b c ->-    ProcessA a (b, Event (ProcessA a b c)) c-rSwitch p = rSwitch' (p *** Cat.id) >>> arr fst-  where-    rSwitch' pid = kSwitch pid test $ \_ p' -> rSwitch'' (p' *** Cat.id)-    rSwitch'' pid = dkSwitch pid test $ \s _ -> rSwitch' s-    test = proc (_, (_, r)) -> returnA -< r---drSwitch ::-    ArrowApply a => ProcessA a b c ->-    ProcessA a (b, Event (ProcessA a b c)) c--drSwitch p =  drSwitch' (p *** Cat.id)-  where-    drSwitch' pid = dSwitch pid $ \p' -> drSwitch' (p' *** Cat.id)---kSwitch ::-    ArrowApply a =>-    ProcessA a b c ->-    ProcessA a (b, c) (Event t) ->-    (ProcessA a b c -> t -> ProcessA a b c) ->-    ProcessA a b c-kSwitch sf test =-    ggSwitch-        (\(CompositeStep _ (CompositeStep (ParStep IDStep sf') _)) -> sf')-        (CompositeStep (ArrStep (id &&& id))-           (CompositeStep (ParStep IDStep sf) (arr snd &&& test)))---dkSwitch ::-    ArrowApply a =>-    ProcessA a b c ->-    ProcessA a (b, c) (Event t) ->-    (ProcessA a b c -> t -> ProcessA a b c) ->-    ProcessA a b c-dkSwitch sf test =-    dggSwitch-        (\(CompositeStep _ (CompositeStep (ParStep IDStep sf') _)) -> sf')-        (CompositeStep (ArrStep (id &&& id))-           (CompositeStep (ParStep IDStep sf) (arr snd &&& test)))--ggSwitch ::-    (ArrowApply a, Stepper a b (c, Event t) sWhole) =>-    (sWhole -> s) ->-    sWhole ->-    (s -> t -> ProcessA a b c) ->-    ProcessA a b c-ggSwitch picker whole k = makePA-    (proc x ->-      do-        let-        (hyevt, whole') <- step whole -<< x-        let hy = fst <$> hyevt-            hevt = snd <$> hyevt-        (case (helperToMaybe hevt)-          of-            Just (Event t) -> step (k (picker whole') t)-            _ -> arr $ const (hy, ggSwitch picker whole' k))-                -<< x)-    (arr fst . suspend whole)--dggSwitch ::-    (ArrowApply a, Stepper a b (c, Event t) sWhole) =>-    (sWhole -> s) ->-    sWhole ->-    (s -> t -> ProcessA a b c) ->-    ProcessA a b c-dggSwitch picker whole k = makePA-    (proc x ->-      do-        let-        (hyevt, whole') <- step whole -<< x-        let hy = fst <$> hyevt-            hevt = snd <$> hyevt-        (case (helperToMaybe hevt)-          of-            Just (Event t) -> arr $ const (hy, k (picker whole') t)-            _ -> arr $ const (hy, dggSwitch picker whole' k))-                -<< x)-    (arr fst . suspend whole)--gSwitch ::-    ArrowApply a =>-    ProcessA a b (p, r) ->-    ProcessA a p q ->-    ProcessA a (q, r) (c, Event t) ->-    (ProcessA a p q -> t -> ProcessA a b c) ->-    ProcessA a b c-gSwitch pre sf post =-    ggSwitch-        (\(CompositeStep _ (CompositeStep (ParStep sf' IDStep) _)) -> sf')-        (CompositeStep pre (CompositeStep (ParStep sf IDStep) post))--dgSwitch ::-    ArrowApply a =>-    ProcessA a b (p, r) ->-    ProcessA a p q ->-    ProcessA a (q, r) (c, Event t) ->-    (ProcessA a p q -> t -> ProcessA a b c) ->-    ProcessA a b c-dgSwitch pre sf post =-    dggSwitch-        (\(CompositeStep _ (CompositeStep (ParStep sf' IDStep) _)) -> sf')-        (CompositeStep pre (CompositeStep (ParStep sf IDStep) post))--broadcast ::-    Functor col =>-    b -> col sf -> col (b, sf)-broadcast x sfs = fmap (\sf -> (x, sf)) sfs--par ::-    (ArrowApply a, Tv.Traversable col) =>-    (forall sf. (b -> col sf -> col (ext, sf))) ->-    col (ProcessA a ext c) ->-    ProcessA a b (col c)-par r sfs = toProcessA (PluralStep r sfs)--parB ::-    (ArrowApply a, Tv.Traversable col) =>-    col (ProcessA a b c) ->-    ProcessA a b (col c)-parB = par broadcast---data PluralStep ext col a b c-  where-    PluralStep ::-        (forall sf. (b -> col sf -> col (ext, sf))) ->-        (col (ProcessA a ext c)) ->-        PluralStep ext col a b c---instance-    (ArrowApply a, Tv.Traversable col) =>-    Stepper a b (col c) (PluralStep ext col a b c)-  where-    feed (PluralStep r sfs) = parCore r sfs >>> arr (runIdentity *** PluralStep r)-    sweep (PluralStep r sfs) = parCore r sfs >>> arr (id *** PluralStep r)-    suspend (PluralStep r sfs) = suspendAll r sfs--suspendAll ::-    (ArrowApply a, Tv.Traversable col) =>-    (forall sf. (b -> col sf -> col (ext, sf))) ->-    col (ProcessA a ext c) ->-    b -> col c-suspendAll r sfs = (sus <$>) . (r `flip` sfs)-  where-    sus (ext, sf) = suspend sf ext--traverseResult ::-    forall h col c.-    (Tv.Traversable col, ProcessHelper h) =>-    col (h c, c) -> h (col c)-traverseResult zs =-    let-        pr :: (h c, c) -> StateT Bool h c-        pr (hx, d) =-          do-            let mx = helperToMaybe hx-            if isJust mx then put True else return ()-            return (fromMaybe d mx)-        hxs = runStateT (Tv.sequence (pr <$> zs)) False-        exist = fromMaybe False $ helperToMaybe (snd <$> hxs)-        result = fst <$> hxs-      in-        if exist then result else join (weakly result)--parCore ::-    (ArrowApply a, Tv.Traversable col, ProcessHelper h) =>-    (forall sf. (b -> col sf -> col (ext, sf))) ->-    col (ProcessA a ext c) ->-    a b (h (col c), col (ProcessA a ext c))--parCore r sfs = proc x ->-  do-    let input = r x sfs-    ret <- unwrapArrow (Tv.sequenceA (fmap (WrapArrow . app') input)) -<< ()-    let zs = traverseResult $ fmap fst ret-        sfs' = fmap snd ret-    returnA -< (zs, sfs')-  where-    app' (y, sf) = proc () ->-      do-        (hz, sf') <- step sf -< y-        returnA -< ((hz, suspend sf' y), sf')---pSwitch ::-    (ArrowApply a, Tv.Traversable col) =>-    (forall sf. (b -> col sf -> col (ext, sf))) ->-    col (ProcessA a ext c) ->-    ProcessA a (b, col c) (Event mng) ->-    (col (ProcessA a ext c) -> mng -> ProcessA a b (col c)) ->-    ProcessA a b (col c)-pSwitch r sfs test =-    ggSwitch-        (\(CompositeStep _-            (CompositeStep (ParStep IDStep (PluralStep _ sfs')) _)) -> sfs')-        (CompositeStep (ArrStep (id &&& id))-            (CompositeStep (ParStep IDStep (PluralStep r sfs)) (arr snd &&& test)))--pSwitchB ::-    (ArrowApply a, Tv.Traversable col) =>-    col (ProcessA a b c) ->-    ProcessA a (b, col c) (Event mng) ->-    (col (ProcessA a b c) -> mng -> ProcessA a b (col c)) ->-    ProcessA a b (col c)-pSwitchB = pSwitch broadcast--dpSwitch ::-    (ArrowApply a, Tv.Traversable col) =>-    (forall sf. (b -> col sf -> col (ext, sf))) ->-    col (ProcessA a ext c) ->-    ProcessA a (b, col c) (Event mng) ->-    (col (ProcessA a ext c) -> mng -> ProcessA a b (col c)) ->-    ProcessA a b (col c)-dpSwitch r sfs test =-    dggSwitch-        (\(CompositeStep _-            (CompositeStep (ParStep IDStep (PluralStep _ sfs')) _)) -> sfs')-        (CompositeStep (ArrStep (id &&& id))-            (CompositeStep (ParStep IDStep (PluralStep r sfs)) (arr snd &&& test)))--dpSwitchB ::-    (ArrowApply a, Tv.Traversable col) =>-    col (ProcessA a b c) ->-    ProcessA a (b, col c) (Event mng) ->-    (col (ProcessA a b c) -> mng -> ProcessA a b (col c)) ->-    ProcessA a b (col c)-dpSwitchB = dpSwitch broadcast--rpSwitch ::-    (ArrowApply a, Tv.Traversable col) =>-    (forall sf. (b -> col sf -> col (ext, sf))) ->-    col (ProcessA a ext c) ->-    ProcessA a-        (b, Event (col (ProcessA a ext c) -> col (ProcessA a ext c)))-        (col c)-rpSwitch r sfs =-    ggSwitch-        (\(ParStep (PluralStep _ sfs') IDStep) -> sfs')-        (ParStep (PluralStep r sfs) IDStep)-        (\sfs' tr -> next r (tr sfs'))-  where-    next ::-        (ArrowApply a, Tv.Traversable col) =>-        (forall sf. (b -> col sf -> col (ext, sf))) ->-        col (ProcessA a ext c) ->-        ProcessA a-            (b, Event (col (ProcessA a ext c) -> col (ProcessA a ext c)))-            (col c)-    next r' sfs' =-        dggSwitch-            (\(ParStep (PluralStep _ sfs'') IDStep) -> sfs'')-            (ParStep (PluralStep r' sfs') IDStep)-            (\sfs'' _ -> rpSwitch r' sfs'')---rpSwitchB ::-    (ArrowApply a, Tv.Traversable col) =>-    col (ProcessA a b c) ->-    ProcessA a-        (b, Event (col (ProcessA a b c) -> col (ProcessA a b c)))-        (col c)-rpSwitchB = rpSwitch broadcast---drpSwitch ::-    (ArrowApply a, Tv.Traversable col) =>-    (forall sf. (b -> col sf -> col (ext, sf))) ->-    col (ProcessA a ext c) ->-    ProcessA a-        (b, Event (col (ProcessA a ext c) -> col (ProcessA a ext c)))-        (col c)-drpSwitch r sfs =-    dggSwitch-        (\(ParStep (PluralStep _ sfs') IDStep) -> sfs')-        (ParStep (PluralStep r sfs) IDStep)-        (\sfs' tr -> drpSwitch r (tr sfs'))--drpSwitchB ::-    (ArrowApply a, Tv.Traversable col) =>-    col (ProcessA a b c) ->-    ProcessA a-        (b, Event (col (ProcessA a b c) -> col (ProcessA a b c)))-        (col c)-drpSwitchB = drpSwitch broadcast-------- Unsafe primitives------- | Repeatedly call `p`.------ How many times `p` is called is indefinite.--- So `p` must satisfy the equation below;------ @p &&& (p >>> arr null) === p &&& arr (const True)@------ where------ @null = getAll . foldMap (\_ -> All False)@-unsafeExhaust ::-    (ArrowApply a, Fd.Foldable f) =>-    a b (f c) ->-    ProcessA a b (Event c)-unsafeExhaust p =-    go >>> fork-  where-    go = ProcessA {-        paFeed = p >>> arr (\y -> (Event y, go)),-        paSweep = p >>> arr (\y -> (if nullFd y then Nothing else Just (Event y), go)),-        paSuspend = const NoEvent-      }--    fork = repeatedly $ await >>= Fd.mapM_ yield--    nullFd = getAll . Fd.foldMap (\_ -> All False)--------- Running---------- Running Monad (To be exported)----data RunInfo a i o m = RunInfo {-    freezeRI :: !(ProcessA a i o),-    getInputRI :: !i,-    getPaddingRI :: !i,-    getPhaseRI :: !Phase,-    getFitRI :: !(forall p q. a p q -> p -> m q)-  }--type RM a i o m = StateT (RunInfo a i o m) m--runRM ::-    (Monad m, ArrowApply a) =>-    (forall p q. a p q -> p -> m q) ->-    ProcessA a (Event i) o ->-    RM a (Event i) o m x ->-    m x-runRM f pa mx =-    evalStateT mx $-        RunInfo {-            freezeRI = pa,-            getInputRI = NoEvent,-            getPaddingRI = NoEvent,-            getPhaseRI = Sweep,-            getFitRI = f-          }----feed_ ::-    (Monad m, MonadState (RunInfo a i o m') m) =>-    i -> i -> m Bool-feed_ input padding =-  do-    ph <- gets getPhaseRI-    if ph == Suspend-        then-          do-            ri <- get-            put $ ri {-                getInputRI = input,-                getPaddingRI = padding,-                getPhaseRI = Feed-              }-            return True-        else-            return False--feedR ::-    (Monad m, MonadState (RunInfo a (Event i) o m') m) =>-    i -> m Bool-feedR x = feed_ (Event x) NoEvent---freeze ::-    Monad m =>-    RM a i o m (ProcessA a i o)-freeze = gets freezeRI--sweepR ::-    Monad m =>-    RM a i o m o-sweepR =-  do-    pa <- freeze-    ph <- gets getPhaseRI-    ri <- get-    case ph of-      Feed ->-        do-            fit0 <- gets getFitRI-            x <- gets getInputRI-            (y, pa') <- lift $ fit0 (feed pa) x-            put $ ri {-                freezeRI = pa',-                getPhaseRI = Sweep-              }-            return y-      Sweep ->-        do-            fit0 <- gets getFitRI-            x <- gets getPaddingRI-            (my, pa') <- lift $ fit0 (sweep pa) x-            put $ ri {-                freezeRI = pa',-                getPhaseRI = if isJust my then Sweep else Suspend-              }-            return $ fromMaybe (suspend pa x) my-      Suspend ->-        do-            x <- gets getPaddingRI-            return $ suspend pa x---sweepAll ::-    (ArrowApply a, Monoid r, Monad m) =>-    (o->r) ->-    ContT Bool (StateT r (RM a i (Event o) m)) ()-sweepAll outpre =-    callCC $ \sus -> forever $ cond sus >> body-  where-    cond sus =-      do-        ph <- lift $ lift $ gets getPhaseRI-        if ph == Suspend then sus () else return ()-    body =-      do-        evx <- lift $ lift $ sweepR-        case evx-          of-            Event x ->-              do-                lift $ modify' (`mappend` outpre x)-            NoEvent ->-                return ()-            End ->-                breakCont False--breakCont :: Monad m => r -> ContT r m a-breakCont = ContT . const . return----- | Run a machine with results concatenated in terms of a monoid.-runOn ::-    (ArrowApply a, Monoid r, Fd.Foldable f) =>-    (c -> r) ->-    ProcessA a (Event b) (Event c) ->-    a (f b) r-runOn outpre pa0 = unArrowMonad $ \xs ->-    runRM arrowMonad pa0 $ execStateT `flip` mempty $-      do-        _ <- evalContT $-          do-            -- Sweep initial events.-            sweepAll outpre--            -- Feed values-            Fd.mapM_ feedSweep xs--            return True--        -- Terminate.-        _ <- lift $ feed_ End End-        evalContT $ sweepAll outpre >> return True--  where-    feedSweep x =-      do-        _ <- lift $ lift $ feedR x-        sweepAll outpre---newtype Builder a = Builder {-    unBuilder :: forall b. (a -> b -> b) -> b -> b-  }-instance-    Monoid (Builder a)-  where-    mempty = Builder $ \_ e -> e-    Builder g `mappend` Builder f =-        Builder $ \c e -> g c (f c e)---- | Run a machine.-run ::-    ArrowApply a =>-    ProcessA a (Event b) (Event c) ->-    a [b] [c]-run pa =-    runOn (\x -> Builder $ \c e -> c x e) pa >>>-    arr (\b -> build (unBuilder b))---- | Run a machine discarding all results.-run_ ::-    ArrowApply a =>-    ProcessA a (Event b) (Event c) ->-    a [b] ()-run_ pa =-    runOn (const ()) pa----- | Represents return values and informations of step executions.-data ExecInfo fa =-    ExecInfo-      {-        yields :: fa, -- ^ Values yielded while the step.-        hasConsumed :: Bool, -- ^ True if the input value is consumed.-            ---            -- False if the machine has stopped unless consuming the input.-            ---            -- Or in the case of `stepYield`, this field become false when-            -- the machine produces a value unless consuming the input.-        hasStopped :: Bool -- ^ True if the machine has stopped at the end of the step.-      }-    deriving (Eq, Show)--instance-    Alternative f => Monoid (ExecInfo (f a))-  where-    mempty = ExecInfo empty False False-    ExecInfo y1 c1 s1 `mappend` ExecInfo y2 c2 s2 =-        ExecInfo (y1 <|> y2) (c1 || c2) (s1 || s2)----- | Execute until an input consumed and the machine suspends.-stepRun ::-    ArrowApply a =>-    ProcessA a (Event b) (Event c) ->-    a b (ExecInfo [c], ProcessA a (Event b) (Event c))-stepRun pa0 = unArrowMonad $ \x ->-  do-    ((csmd, ct, pa), r)  <- runRM arrowMonad pa0 $ runStateT `flip` mempty $-      do-        csmd <- evalContT $-          do-            sweepAll singleton-            return True-        ct <- evalContT $-          do-            _ <- lift $ lift $ feedR x-            sweepAll singleton-            return True-        pa <- lift $ freeze-        return (csmd, ct, pa)-    return $ (retval r csmd ct, pa)-  where-    singleton x = Endo (x:)--    retval r csmd ct = ExecInfo {-        yields = appEndo r [],-        hasConsumed = csmd,-        hasStopped = not ct-      }---- | Execute until an output produced.-stepYield ::-    ArrowApply a =>-    ProcessA a (Event b) (Event c) ->-    a b (ExecInfo (Maybe c), ProcessA a (Event b) (Event c))-stepYield pa0 = unArrowMonad $ \x -> runRM arrowMonad pa0 $ evalStateT `flip` mempty $-  do-    go x-    r <- get-    pa <- lift freeze-    return (r, pa)--  where-    go x =-      do-        csmd <- lift $ feedR x-        modify $ \ri -> ri { hasConsumed = csmd }--        evo <- lift sweepR--        case evo-          of-            Event y ->-              do-                modify $ \ri -> ri { yields = Just y }--            NoEvent ->-              do-                csmd' <- gets hasConsumed-                if csmd' then return () else go x--            End ->-                modify $ \ri -> ri { hasStopped = True }-+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE KindSignatures #-}++module+    Control.Arrow.Machine.Types+      (+        -- * Stream transducer type+        ProcessT(),+        ProcessA,++        -- * Event type and utility+        Occasional' (..),+        Occasional (..),+        Event (),+        noEvent,+        end,+        ZeroEvent(..),+        condEvent,+        filterEvent,+        filterJust,+        filterLeft,+        filterRight,+        splitEvent,+        evMap,++        -- * Coroutine monad+        -- | Procedural coroutine monad that can await or yield values.+        --+        -- Coroutines can be encoded to machines by `constructT` or so on and+        -- then put into `ProcessT` compositions.+        PlanT(..),+        Plan,++        MonadAwait (..),+        MonadYield (..),+        MonadStop (..),+        catchP,++        stopped,+        muted,++        -- * Constructing machines from plans+        constructT,+        repeatedlyT,++        construct,+        repeatedly,++        -- * Evolution monad+        -- | Time-evolution monad, or generalized plan monad.+        Evolution(..),+        packProc,+        awaitProc,+        yieldProc,++        -- * Running machines (at once)+        runT,+        runT_,+        run,+        run_,++        -- * Running machines (step-by-step)+        stepRun,+        stepYield,++        -- * Primitive machines - switches+        -- | Switches inspired by the Yampa library.+        -- Signature is almost same, but collection requirement is  not only 'Functor',+        -- but 'Tv.Traversable'. This is because of side effects.+        switch,+        dSwitch,+        rSwitch,+        drSwitch,+        kSwitch,+        dkSwitch,+        gSwitch,+        dgSwitch,+        pSwitch,+        pSwitchB,+        dpSwitch,+        dpSwitchB,+        rpSwitch,+        rpSwitchB,+        drpSwitch,+        drpSwitchB,+        par,+        parB,++        -- * Primitive machines - other safe primitives+        fit,+        fitW,++        -- * Primitive machines - unsafe+        unsafeExhaust,+      )+where++import qualified Control.Category as Cat+import Data.Profunctor (Profunctor, dimap, rmap)+import Data.Void+import Control.Arrow+import Control.Monad+import Control.Monad.Trans+import Control.Monad.State.Strict+import Control.Monad.Reader+import Control.Monad.Writer hiding ((<>))+import Control.Monad.Identity+import Control.Monad.Trans.Cont+import Control.Applicative+import qualified Data.Foldable as Fd+import Data.Traversable as Tv+import Data.Semigroup (Semigroup, (<>))+import Data.Maybe (fromMaybe, isNothing, isJust)+import qualified Control.Monad.Trans.Free.Church as F+import GHC.Exts (build)+++-- | To get multiple outputs by one input, the `Phase` parameter is introduced.+--+-- Once a value `Feed`ed, the machine is `Sweep`ed until it `Suspend`s.+data Phase = Feed | Sweep | Suspend deriving (Eq, Show)++instance+    Monoid Phase+  where+    mempty = Sweep++    mappend Feed _ = Feed+    mappend _ Feed = Feed+    mappend Suspend _ = Suspend+    mappend _ Suspend = Suspend+    mappend Sweep Sweep = Sweep+++type ProcType a b c = ProcessT a b c++class Stepper m b c s | s -> m, s -> b, s -> c+  where+    feed :: s -> b -> m (c, s)+    sweep :: s -> b -> m (Maybe c, s)+    suspend :: s -> b -> c++-- | The stream transducer arrow.+--+-- To construct `ProcessT` instances, use `Control.Arrow.Machine.Plan.Plan`,+-- `arr`, functions declared in `Control.Arrow.Machine.Utils`,+-- or arrow combinations of them.+--+-- See an introduction at "Control.Arrow.Machine" documentation.+data ProcessT m b c = ProcessT {+    paFeed :: b -> m (c, ProcessT m b c),+    paSweep :: b -> m (Maybe c, ProcessT m b c),+    paSuspend :: !(b -> c)+  }++-- | Isomorphic to ProcessT when 'a' is ArrowApply.+type ProcessA a = ProcessT (ArrowMonad a)++instance+    Stepper a b c (ProcessT a b c)+  where+    feed = paFeed+    sweep = paSweep+    suspend = paSuspend++toProcessT ::+    (Monad m, Stepper m b c s) =>+    s -> ProcessT m b c+toProcessT s = ProcessT {+    paFeed = liftM (second toProcessT) . feed s,+    paSweep = liftM (second toProcessT) . sweep s,+    paSuspend = suspend s+  }+{-# INLINE[2] toProcessT  #-}++-- For internal use+class+    (Applicative f, Monad f) => ProcessHelper f+  where+    step ::+        (Monad m, Stepper m b c s) =>+        s -> b -> m (f c, s)+    helperToMaybe :: f a -> Maybe a+    weakly :: a -> f a++    compositeStep ::+        (Monad m, Stepper m b p s1, Stepper m p c s2) =>+        s1 -> s2 ->+        b -> m (f c, s1, s2)+++instance+    ProcessHelper Identity+  where+    step pa = liftM (first Identity) . feed pa+    helperToMaybe = Just . runIdentity+    weakly = Identity+    compositeStep sf test x =+      do+        (y, sf') <- feed sf x+        (z, test') <- feed test y+        return (return z, sf', test')++instance+    ProcessHelper Maybe+  where+    step = sweep+    helperToMaybe = id+    weakly _ = Nothing+    compositeStep sf0 test0 x =+      do+        let y = suspend sf0 x+        (mt, test') <- sweep test0 y+        case mt+          of+            Just t -> return (Just t, sf0, test')+            Nothing -> next sf0 test'++      where+        next sf test =+          do+            (my, sf') <- sweep sf x+            case my+              of+                Just y -> next2 y sf' test+                Nothing -> return (Nothing, sf', test)++        next2 y sf test =+          do+            (t, test') <- feed test y+            return (Just t, sf, test')++makePA ::+    Monad m =>+    (forall f. ProcessHelper f =>+        b -> m (f c, ProcessT m b c)) ->+    (b -> c) ->+    ProcessT m b c+makePA h !sus = ProcessT {+    paFeed = liftM (first runIdentity) . h,+    paSweep = h,+    paSuspend = sus+  }+++data CompositeStep m b c s1 s2+  where+    CompositeStep ::+        (Stepper m b p s1, Stepper m p c s2) =>+        s1 -> s2 ->+        CompositeStep m b c s1 s2++instance+    Monad m => Stepper m b c (CompositeStep m b c s1 s2)+  where+    feed (CompositeStep s1 s2) x =+      do+        (fz, s1', s2') <- compositeStep s1 s2 x+        return (runIdentity fz, CompositeStep s1' s2')+    sweep (CompositeStep s1 s2) x =+      do+        (fz, s1', s2') <- compositeStep s1 s2 x+        return (fz, CompositeStep s1' s2')+    suspend (CompositeStep s1 s2) =+        suspend s2 . suspend s1+++data IDStep m b c+  where+    IDStep :: IDStep (m :: * -> *) b b++instance+    Monad m => Stepper m b c (IDStep m b c)+  where+    feed IDStep x = return (x, IDStep)+    sweep IDStep _ = return (Nothing, IDStep)+    suspend IDStep = id++newtype ArrStep (m :: * -> *) b c = ArrStep (b -> c)++instance+    Monad m => Stepper m b c (ArrStep m b c)+  where+    feed (ArrStep f) x = return (f x, ArrStep f)+    sweep (ArrStep f) _ = return (Nothing, ArrStep f)+    suspend (ArrStep f) = f+++data ParStep m b c s1 s2+  where+    ParStep ::+        (Stepper m b1 c1 s1, Stepper m b2 c2 s2) =>+        s1 -> s2 ->+        ParStep m (b1, b2) (c1, c2) s1 s2++instance+    Monad m => Stepper m b c (ParStep m b c s1 s2)+  where+    feed (ParStep f g)  (x1, x2) =+      do+        (y1, f') <- feed f x1+        (y2, g') <- feed g x2+        return ((y1, y2), ParStep f' g')+    sweep (ParStep f g) (x1, x2) =+      do+        (my1, f') <- sweep f x1+        (my2, g') <- sweep g x2+        let y1 = fromMaybe (suspend f' x1) my1 -- suspend f ?+            y2 = fromMaybe (suspend g' x2) my2+            r = if (isNothing my1 && isNothing my2) then Nothing else Just (y1, y2)+        return (r, ParStep f' g')+    suspend (ParStep f g) = suspend f *** suspend g+++-- |Natural transformation+fit ::+    (Monad m, Monad m') =>+    (forall p. m p -> m' p) ->+    ProcessT m b c -> ProcessT m' b c+fit f pa =+    arr Identity >>>+    fitW runIdentity (\ar (Identity x) -> f (ar x)) pa++-- |Experimental: more general fit.+--+-- Should w be a comonad?+fitW :: (Monad m, Monad m', Functor w) =>+    (forall p. w p -> p) ->+    (forall p q. (p -> m q) -> w p -> m' q) -> +    ProcessT m b c -> ProcessT m' (w b) c+fitW extr f pa = makePA+    (liftM (second $ fitW extr f) . f (step pa))+    (extr >>> suspend pa)++instance+    Monad m => Profunctor (ProcessT m)+  where+    dimap = dimapProc+    {-# INLINE dimap #-}++dimapProc ::+    Monad m =>+    (b->c)->(d->e)->+    ProcType m c d -> ProcType m b e+dimapProc f g pa = makePA+    (liftM (fmap g *** dimapProc f g) . step pa . f)+    (dimap f g (suspend pa))++{-# NOINLINE dimapProc #-}+++instance+    Monad m => Functor (ProcessT m i)+  where+    fmap = rmap++instance+    Monad m => Applicative (ProcessT m i)+  where+    pure = arr . const+    pf <*> px = (pf &&& px) >>> arr (uncurry ($))++instance+    (Monad m, Monoid o) => Monoid (ProcessT m i o)+  where+    mempty = pure mempty+    mappend = liftA2 mappend++instance+    Monad m => Cat.Category (ProcessT m)+  where+    id = idProc+    {-# INLINE id #-}++    g . f = compositeProc f g+    {-# INLINE (.) #-}+++instance+    Monad m => Arrow (ProcessT m)+  where+    arr = arrProc+    {-# INLINE arr #-}++    first pa = parProc pa idProc+    {-# INLINE first #-}++    second pa = parProc idProc pa+    {-# INLINE second #-}++    (***) = parProc+    {-# INLINE (***) #-}+++parProc :: Monad m =>+    ProcType m b c ->+    ProcType m d e ->+    ProcType m (b, d) (c, e)+parProc f g = toProcessT $ ParStep f g+{-# INLINE [0] parProc #-}++idProc :: Monad m => ProcType m b b+idProc = let pa = makePA (\x -> return (weakly x, pa)) id in pa+{-# NOINLINE idProc #-}++arrProc :: Monad m => (b->c) -> ProcType m b c+arrProc f = let pa = makePA (\x -> return (weakly (f x), pa)) f in pa+{-# NOINLINE arrProc #-}++-- |Composition is proceeded by the backtracking strategy.+compositeProc :: Monad m =>+              ProcType m b d -> ProcType m d c -> ProcType m b c+compositeProc f0 g0 = ProcessT {+    paFeed = \x ->+      do+        (y, f') <- feed f0 x+        (z, g') <- feed g0 y+        return (z, compositeProc f' g'),+    paSweep = \x ->+      do+        (mz, g') <- sweep g0 $ suspend f0 x+        case mz+          of+            Just z -> return (Just z, compositeProc f0 g')+            Nothing -> btrk f0 g' x,+    paSuspend = suspend f0 >>> suspend g0+  }+  where+    btrk f g x =+      do+        (my, f') <- sweep f x+        (mz, g') <-+            case my+              of+                Just y ->+                  do+                    (z, g') <- feed g y+                    return (Just z, g')+                Nothing ->+                    return (Nothing, g)+        return (mz, compositeProc f' g')++{-# NOINLINE compositeProc #-}++-- rules+{-# RULES+"ProcessT: id/*"+    forall g. compositeProc idProc g = g+"ProcessT: */id"+    forall f. compositeProc f idProc = f++"ProcessT: concat/concat"+    forall f g h. compositeProc (compositeProc f g) h = compositeProc f (compositeProc g h)++"ProcessT: dimap/dimap"+    forall f g h i j. dimapProc f j (dimapProc g i h)  = dimapProc (g . f) (j . i) h+"ProcessT: dimap/arr"+    forall f g h. dimapProc f h (arrProc g) = arrProc (h . g . f)++"ProcessT: arr***/par"+    forall f1 f2 g1 g2 h. compositeProc (parProc f1 (arrProc f2)) (compositeProc (parProc g1 g2) h) =+        compositeProc (parProc (compositeProc f1 g1) (dimapProc f2 id g2)) h+"ProcessT: arr***/par-2"+    forall f1 f2 g1 g2. compositeProc (parProc f1 (arrProc f2)) (parProc g1 g2) =+        parProc (compositeProc f1 g1) (dimapProc f2 id g2)+"ProcessT: par/***arr"+    forall f1 f2 g1 g2 h. compositeProc (parProc f1 f2) (compositeProc (parProc (arrProc g1) g2) h) =+        compositeProc (parProc (dimapProc id g1 f1) (compositeProc f2 g2)) h+"ProcessT: par/***arr-2"+    forall f1 f2 g1 g2. compositeProc (parProc f1 f2) (parProc (arrProc g1) g2) =+        parProc (dimapProc id g1 f1) (compositeProc f2 g2)++"ProcessT: first/par"+    forall f1 g1 g2 h. compositeProc (parProc f1 idProc) (compositeProc (parProc g1 g2) h) =+        compositeProc (parProc (compositeProc f1 g1) g2) h+"ProcessT: first/par-2"+    forall f1 g1 g2. compositeProc (parProc f1 idProc) (parProc g1 g2) =+        parProc (compositeProc f1 g1) g2+"ProcessT: par/second"+    forall f1 f2 g2 h. compositeProc (parProc f1 f2) (compositeProc (parProc idProc g2) h) =+        compositeProc (parProc f1 (compositeProc f2 g2)) h+"ProcessT: par/second-2"+    forall f1 f2 g2. compositeProc (parProc f1 f2) (parProc idProc g2) =+        parProc f1 (compositeProc f2 g2)++"ProcessT: arr/arr"+    forall f g h. compositeProc (arrProc f) (compositeProc (arrProc g) h) =+        compositeProc (arrProc (g . f)) h+"ProcessT: arr/arr-2"+    forall f g. compositeProc (arrProc f) (arrProc g) = arrProc (g . f)+"ProcessT: arr/*" [1]+    forall f g. compositeProc (arrProc f) g = dimapProc f id g+"ProcessT: */arr" [1]+    forall f g. compositeProc f (arrProc g) = dimapProc id g f+"ProcessT: arr***arr" [1]+    forall f g. parProc (arrProc f) (arrProc g) = arrProc (f *** g)+  #-}++instance+    Monad m => ArrowChoice (ProcessT m)+  where+    left pa0 = makePA+        (\eth -> sweep' pa0 eth)+        (left $ suspend pa0)+      where+        sweep' pa (Left x) =+          do+            (my, pa') <- step pa x+            return (Left <$> my, left pa')+        sweep' pa (Right d) =+            return (weakly (Right d), left pa)++instance+    Monad m => ArrowLoop (ProcessT m)+  where+    loop pa =+        makePA+            (\x ->+              do+                (hyd, pa') <- step pa (x, loopSusD x)+                return (fst <$> hyd, loop pa'))+            (loop $ suspend pa)+      where+        loopSusD = loop (suspend pa >>> \(_, d) -> (d, d))+++-- | Discrete events on a time line.+-- Created and consumed by various transducers.+data Event a = Event a | NoEvent | End+++instance+    Functor Event+  where+    fmap _ NoEvent = NoEvent+    fmap _ End = End+    fmap f (Event x) = Event (f x)+++instance+    Semigroup a => Monoid (Event a)+  where+    mempty = End+    Event x `mappend` Event y = Event (x <> y)+    Event x `mappend` _ = Event x+    _ `mappend` Event y = Event y+    NoEvent `mappend` _ = NoEvent+    _ `mappend` NoEvent = NoEvent+    _ `mappend` _ = End++++-- | Signals that can be absent(`NoEvent`) or end.+-- For composite structure, `collapse` can be defined as monoid sum of all member occasionals.+class+    Occasional' a+  where+    collapse :: a -> Event ()++-- | Occasional signals with creation methods.+class+    Occasional' a => Occasional a+  where+    burst :: Event Void -> a+++instance+    (Occasional' a, Occasional' b) => Occasional' (a, b)+  where+    collapse (x, y) = collapse x `mappend` collapse y++instance+    (Occasional a, Occasional b) => Occasional (a, b)+  where+    burst = burst &&& burst++instance+    Occasional' (Event a)+  where+    collapse = (() <$)++instance+    Occasional (Event a)+  where+    burst = fmap absurd++noEvent :: Occasional a => a+noEvent = burst NoEvent++end :: Occasional a => a+end = burst End++data ZeroEvent = ZeroEvent deriving (Eq, Show, Enum, Bounded)++instance+    Monoid ZeroEvent+  where+    mempty = ZeroEvent+    mappend _ _ = ZeroEvent++instance+    Occasional' ZeroEvent+  where+    collapse _ = mempty+++condEvent :: Bool -> Event a -> Event a+condEvent _ End = End+condEvent True ev = ev+condEvent False _ = NoEvent++filterEvent ::+    Arrow ar =>+    (a -> Bool) ->+    ar (Event a) (Event a)+filterEvent cond = filterJust <<< evMap mcond+  where+    mcond x+        | cond x = Just x+        | otherwise = Nothing++filterJust ::+    Arrow ar => ar (Event (Maybe a)) (Event a)+filterJust = arr filterJust'+  where+    filterJust' (Event (Just x)) = Event x+    filterJust' (Event Nothing) = NoEvent+    filterJust' NoEvent = NoEvent+    filterJust' End = End++-- |Split an event stream.+--+-- >>> run (filterLeft) [Left 1, Right 2, Left 3, Right 4]+-- [1,3]+filterLeft ::+    Arrow ar =>+    ar (Event (Either a b)) (Event a)+filterLeft = filterJust <<< evMap (either Just (const Nothing))++-- |Split an event stream.+--+-- >>> run filterRight [Left 1, Right 2, Left 3, Right 4]+-- [2,4]+filterRight ::+    Arrow ar =>+    ar (Event (Either a b)) (Event b)+filterRight = filterJust <<< evMap (either (const Nothing) Just)++-- |Split an event stream.+--+-- >>> run (splitEvent >>> arr fst) [Left 1, Right 2, Left 3, Right 4]+-- [1,3]+--+-- >>> run (splitEvent >>> arr snd) [Left 1, Right 2, Left 3, Right 4]+-- [2,4]+splitEvent ::+    Arrow ar =>+    ar (Event (Either a b)) (Event a, Event b)+splitEvent = filterLeft &&& filterRight++-- | Alias of "arr . fmap"+--+-- While "ProcessT a (Event b) (Event c)" means a transducer from b to c,+-- function b->c can be lifted into a transducer by fhis function.+--+-- But in most cases you needn't call this function in proc-do notations,+-- because `arr`s are completed automatically while desugaring.+--+-- For example,+--+-- @+-- proc x -> returnA -\< f \<$\> x+-- @+--+-- is equivalent to+--+-- @+-- evMap f+-- @+evMap ::  Arrow a => (b->c) -> a (Event b) (Event c)+evMap = arr . fmap++++muted ::+    (Monad m, Occasional' b, Occasional c) => ProcessT m b c+muted = arr collapse >>> repeatedly await >>> arr burst++-- | A monad type represents time evolution of ProcessT+newtype Evolution i o m r = Evolution+  {+    runEvolution :: Cont (ProcessT m i o) r+  }+  deriving+    (Functor, Applicative, Monad)++instance+    Occasional o =>+    MonadTrans (Evolution i o)+  where+    {-# INLINE lift #-}+    lift ma = Evolution $ cont $ \fmpf -> packProc (fmpf <$> ma)++instance+    (MonadIO m, Occasional o) =>+    MonadIO (Evolution i o m)+  where+    {-# INLINE liftIO #-}+    liftIO ma = lift $ liftIO ma+++data+    PlanF i o a+  where+    AwaitPF :: (i->a) -> a -> PlanF i o a+    YieldPF :: o -> a -> PlanF i o a+    StopPF :: PlanF i o a++instance+    Functor (PlanF i o)+  where+    fmap g (AwaitPF f ff) = AwaitPF (g . f) (g ff)+    fmap g (YieldPF x r) = YieldPF x (g r)+    fmap _ StopPF = StopPF+++newtype PlanT i o m a =+    PlanT { freePlanT :: F.FT (PlanF i o) m a }+  deriving+    (Functor, Applicative, Monad)++type Plan i o a = forall m. Monad m => PlanT i o m a++packProc ::+    (Monad m, Occasional o) =>+    m (ProcessT m i o) ->+    ProcessT m i o+packProc !mp = ProcessT {+    paFeed = \ex -> mp >>= \p -> feed p ex ,+    paSweep = \ex -> mp >>= \p -> sweep p ex,+    paSuspend = const noEvent+  }+{-# INLINE[0] packProc #-}+{-# RULES+"ProcessT: return/packProc"+    forall p. return (packProc p) = p+ #-}+{-+"ProcessT: packProc/return"+    forall p. packProc (return p) = p+ -}++instance+    MonadTrans (PlanT i o)+  where+    lift mx = PlanT $ lift mx+    {-# INLINE lift #-}++instance+    MonadReader r m => MonadReader r (PlanT i o m)+  where+    ask = lift ask+    local f mx = PlanT $ local f (freePlanT mx)++instance+    MonadWriter w m => MonadWriter w (PlanT i o m)+  where+    tell = lift . tell+    listen mx = PlanT $ listen (freePlanT mx)+    pass mx = PlanT $ pass (freePlanT mx)++instance+    MonadState s m => MonadState s (PlanT i o m)+  where+    get = lift get+    put x = lift $ put x++instance+    Monad m => Alternative (PlanT i o m)+  where+    empty = stop+    (<|>) = catchP++instance+    Monad m => MonadPlus (PlanT i o m)+  where+    mzero = stop+    mplus = catchP++instance+    MonadIO m => MonadIO (PlanT i o m)+  where+    liftIO = lift . liftIO+    {-# INLINE liftIO #-}++class+    MonadAwait m a | m -> a+  where+    await :: m a++instance+    Monad m => MonadAwait (PlanT i o m) i+  where+    {-# INLINE await #-}+    await = PlanT $ F.wrap $ AwaitPF return (F.liftF StopPF)++instance+    (Monad m, Occasional o) =>+    MonadAwait (Evolution (Event a) o m) a+  where+    {-# INLINE await #-}+    await = Evolution $ cont $ \next -> awaitProc next stopped++class+    MonadYield m a | m -> a+  where+    yield :: a -> m ()++instance+    Monad m => MonadYield (PlanT i o m) o+  where+    {-# INLINE yield #-}+    yield x = PlanT $ F.liftF $ YieldPF x ()++instance+    Monad m => MonadYield (Evolution i (Event a) m) a+  where+    {-# INLINE yield #-}+    yield x = Evolution $ cont $ \next -> yieldProc x (next ())++class+    MonadStop m+  where+    stop :: m a++instance+    Monad m => MonadStop (PlanT i o m)+  where+    {-# INLINE stop #-}+    stop = PlanT $ F.liftF StopPF++instance+    (Monad m, Occasional o) =>+    MonadStop (Evolution i o m)+  where+    {-# INLINE stop #-}+    stop = Evolution $ cont $ const stopped++catchP:: Monad m =>+    PlanT i o m a -> PlanT i o m a -> PlanT i o m a++catchP (PlanT pl) next0 =+    PlanT $ F.FT $ \pr free ->+        F.runFT pl pr (free' next0 pr free)+  where+    free' ::+        Monad m =>+        PlanT i o m a ->+        (a -> m r) ->+        (forall x. (x -> m r) -> PlanF i o x -> m r) ->+        (y -> m r) ->+        (PlanF i o y) ->+        m r+    free' (PlanT next) pr free r pl' =+        let nextR = F.runFT next pr free+            go StopPF = nextR+            go (AwaitPF f ff) =+                free (either (\_ -> nextR) r) $ AwaitPF (Right . f) (Left ff)+            go _ = free r pl'+          in+            go pl'++{-# INLINE awaitProc #-}+awaitProc ::+    (Monad m, Occasional o) =>+    (a -> ProcessT m (Event a) o) ->+    ProcessT m (Event a) o ->+    ProcessT m (Event a) o+awaitProc f ff = awaitProc'+  where+    awaitProc' = ProcessT {+        paFeed = awaitFeed,+        paSweep = awaitSweep,+        paSuspend = const noEvent+      }++    awaitFeed (Event x) = feed (f x) NoEvent+    awaitFeed NoEvent = return (noEvent, awaitProc')+    awaitFeed End = feed ff End++    awaitSweep (Event x) = sweep (f x) NoEvent+    awaitSweep NoEvent = return (Nothing, awaitProc')+    awaitSweep End = sweep ff End++{-# INLINE yieldProc #-}+yieldProc ::+    Monad m =>+    a ->+    ProcessT m i (Event a) ->+    ProcessT m i (Event a)+yieldProc y pa = ProcessT {+    paFeed = \_ -> return (Event y, pa),+    paSweep = \_ -> return (Just (Event y), pa),+    paSuspend = const NoEvent+  }++{-# INLINE stopped #-}+stopped ::+    (Monad m, Occasional o) =>+    ProcessT m i o+stopped = ProcessT {+    paFeed = \_ -> return (end, arr (const end)),+    paSweep = \_ -> return (Just end, arr (const end)),+    paSuspend = pure end+  }++{-# INLINE constructT #-}+constructT ::+    (Monad m) =>+    PlanT i o m r ->+    ProcessT m (Event i) (Event o)+constructT pl0 = runCont (runEvolution $ realizePlan pl0) (const stopped)++{-# INLINE realizePlan #-}+realizePlan ::+    Monad m =>+    PlanT i o m a ->+    Evolution (Event i) (Event o) m a+realizePlan pl = Evolution $ cont $ \next ->+    packProc $ F.runFT (freePlanT pl) (return . next) (\b fr -> return $ free (packProc . b <$> fr))+  where+    free ::+        Monad m => PlanF i o (ProcessT m (Event i) (Event o)) -> ProcessT m (Event i) (Event o)+    free (AwaitPF f ff) = awaitProc f ff+    free (YieldPF y pa) = yieldProc y pa+    free StopPF = stopped++{-# INLINE repeatedlyT #-}+repeatedlyT ::+    Monad m =>+    PlanT i o m r ->+    ProcessT m (Event i) (Event o)+repeatedlyT pl0 = runCont (forever $ runEvolution $ realizePlan pl0) absurd+++-- for pure+{-# INLINE construct #-}+construct ::+    Monad m =>+    PlanT i o Identity r ->+    ProcessT m (Event i) (Event o)+construct = fit (return . runIdentity) . constructT++{-# INLINE repeatedly #-}+repeatedly ::+    Monad m =>+    PlanT i o Identity r ->+    ProcessT m (Event i) (Event o)+repeatedly = fit (return . runIdentity) . repeatedlyT+++--+-- Switches+--++-- |Run the 1st transducer at the beggining. Then switch to 2nd when Event t occurs.+--+-- >>> :{+-- let+--     before = proc x ->+--       do+--         trigger <- filterEvent (== 3) -< x+--         returnA -< ((*10) <$> x, trigger)+--     after t = proc x -> returnA -< (*100) <$> x+--  in+--     run (switch before after) [1..5]+-- :}+-- [10,20,300,400,500]+switch ::+    Monad m =>+    ProcessT m b (c, Event t) ->+    (t -> ProcessT m b c) ->+    ProcessT m b c+switch sf k = ggSwitch (const ()) sf (\() -> k)+++-- |Delayed version of `switch`+--+-- >>> :{+-- let+--     before = proc x ->+--       do+--         trigger <- filterEvent (== 3) -< x+--         returnA -< ((*10) <$> x, trigger)+--     after t = proc x -> returnA -< (*100) <$> x+--  in+--     run (dSwitch before after) [1..5]+-- :}+-- [10,20,30,400,500]+dSwitch ::+    Monad m =>+    ProcessT m b (c, Event t) ->+    (t -> ProcessT m b c) ->+    ProcessT m b c+dSwitch sf k = dggSwitch (const ()) sf (\() -> k)++-- |Recurring switch.+--+-- >>> :{+-- let pa = proc evtp ->+--       do+--         evx <- returnA -< fst <$> evtp+--         evarr <- filterJust -< snd <$> evtp+--         rSwitch (evMap (*10)) -< (evx, evarr)+--     l = [(1, Nothing),+--          (2, Just (arr $ fmap (*100))),+--          (3, Nothing),+--          (4, Just (arr $ fmap (*1000))),+--          (5, Nothing)]+--   in+--     run pa l+-- :}+-- [10,200,300,4000,5000]+rSwitch ::+    Monad m =>+    ProcessT m b c ->+    ProcessT m (b, Event (ProcessT m b c)) c+rSwitch p = rSwitch' (p *** Cat.id) >>> arr fst+  where+    rSwitch' pid = kSwitch pid test $ \_ p' -> rSwitch'' (p' *** Cat.id)+    rSwitch'' pid = dkSwitch pid test $ \s _ -> rSwitch' s+    test = proc (_, (_, r)) -> returnA -< r+++-- |Delayed version of `rSwitch`.+--+-- >>> :{+-- let pa = proc evtp ->+--       do+--         evx <- returnA -< fst <$> evtp+--         evarr <- filterJust -< snd <$> evtp+--         drSwitch (evMap (*10)) -< (evx, evarr)+--     l = [(1, Nothing),+--          (2, Just (arr $ fmap (*100))),+--          (3, Nothing),+--          (4, Just (arr $ fmap (*1000))),+--          (5, Nothing)]+--   in+--     run pa l+-- :}+-- [10,20,300,400,5000]+drSwitch ::+    Monad m => ProcessT m b c ->+    ProcessT m (b, Event (ProcessT m b c)) c++drSwitch p =  drSwitch' (p *** Cat.id)+  where+    drSwitch' pid = dSwitch pid $ \p' -> drSwitch' (p' *** Cat.id)+++kSwitch ::+    Monad m =>+    ProcessT m b c ->+    ProcessT m (b, c) (Event t) ->+    (ProcessT m b c -> t -> ProcessT m b c) ->+    ProcessT m b c+kSwitch sf test =+    ggSwitch+        (\(CompositeStep _ (CompositeStep (ParStep IDStep sf') _)) -> sf')+        (CompositeStep (ArrStep (id &&& id))+           (CompositeStep (ParStep IDStep sf) (arr snd &&& test)))+++dkSwitch ::+    Monad m =>+    ProcessT m b c ->+    ProcessT m (b, c) (Event t) ->+    (ProcessT m b c -> t -> ProcessT m b c) ->+    ProcessT m b c+dkSwitch sf test =+    dggSwitch+        (\(CompositeStep _ (CompositeStep (ParStep IDStep sf') _)) -> sf')+        (CompositeStep (ArrStep (id &&& id))+           (CompositeStep (ParStep IDStep sf) (arr snd &&& test)))++ggSwitch ::+    (Monad m, Stepper m b (c, Event t) sWhole) =>+    (sWhole -> s) ->+    sWhole ->+    (s -> t -> ProcessT m b c) ->+    ProcessT m b c+ggSwitch picker whole k = makePA+    (\x ->+      do+        let+        (hyevt, whole') <- step whole x+        let hy = fst <$> hyevt+            hevt = snd <$> hyevt+        case (helperToMaybe hevt)+          of+            Just (Event t) -> step (k (picker whole') t) x+            _ -> return (hy, ggSwitch picker whole' k))+    (arr fst . suspend whole)++dggSwitch ::+    (Monad m, Stepper m b (c, Event t) sWhole) =>+    (sWhole -> s) ->+    sWhole ->+    (s -> t -> ProcessT m b c) ->+    ProcessT m b c+dggSwitch picker whole k = makePA+    (\x ->+      do+        let+        (hyevt, whole') <- step whole x+        let hy = fst <$> hyevt+            hevt = snd <$> hyevt+        case (helperToMaybe hevt)+          of+            Just (Event t) -> return (hy, k (picker whole') t)+            _ -> return (hy, dggSwitch picker whole' k))+    (arr fst . suspend whole)++gSwitch ::+    Monad m =>+    ProcessT m b (p, r) ->+    ProcessT m p q ->+    ProcessT m (q, r) (c, Event t) ->+    (ProcessT m p q -> t -> ProcessT m b c) ->+    ProcessT m b c+gSwitch pre sf post =+    ggSwitch+        (\(CompositeStep _ (CompositeStep (ParStep sf' IDStep) _)) -> sf')+        (CompositeStep pre (CompositeStep (ParStep sf IDStep) post))++dgSwitch ::+    Monad m =>+    ProcessT m b (p, r) ->+    ProcessT m p q ->+    ProcessT m (q, r) (c, Event t) ->+    (ProcessT m p q -> t -> ProcessT m b c) ->+    ProcessT m b c+dgSwitch pre sf post =+    dggSwitch+        (\(CompositeStep _ (CompositeStep (ParStep sf' IDStep) _)) -> sf')+        (CompositeStep pre (CompositeStep (ParStep sf IDStep) post))++broadcast ::+    Functor col =>+    b -> col sf -> col (b, sf)+broadcast x sfs = fmap (\sf -> (x, sf)) sfs++par ::+    (Monad m, Tv.Traversable col) =>+    (forall sf. (b -> col sf -> col (ext, sf))) ->+    col (ProcessT m ext c) ->+    ProcessT m b (col c)+par r sfs = toProcessT (PluralStep r sfs)++parB ::+    (Monad m, Tv.Traversable col) =>+    col (ProcessT m b c) ->+    ProcessT m b (col c)+parB = par broadcast+++data PluralStep ext col m b c+  where+    PluralStep ::+        (forall sf. (b -> col sf -> col (ext, sf))) ->+        (col (ProcessT m ext c)) ->+        PluralStep ext col m b c+++instance+    (Monad m, Tv.Traversable col) =>+    Stepper m b (col c) (PluralStep ext col m b c)+  where+    feed (PluralStep r sfs) = liftM (runIdentity *** PluralStep r) . parCore r sfs+    sweep (PluralStep r sfs) = liftM (id *** PluralStep r) . parCore r sfs+    suspend (PluralStep r sfs) = suspendAll r sfs++suspendAll ::+    (Monad m, Tv.Traversable col) =>+    (forall sf. (b -> col sf -> col (ext, sf))) ->+    col (ProcessT m ext c) ->+    b -> col c+suspendAll r sfs = (sus <$>) . (r `flip` sfs)+  where+    sus (ext, sf) = suspend sf ext++traverseResult ::+    forall h col c.+    (Tv.Traversable col, ProcessHelper h) =>+    col (h c, c) -> h (col c)+traverseResult zs =+    let+        pr :: (h c, c) -> StateT Bool h c+        pr (hx, d) =+          do+            let mx = helperToMaybe hx+            if isJust mx then put True else return ()+            return (fromMaybe d mx)+        hxs = runStateT (Tv.sequence (pr <$> zs)) False+        exist = fromMaybe False $ helperToMaybe (snd <$> hxs)+        result = fst <$> hxs+      in+        if exist then result else join (weakly result)++parCore ::+    (Applicative m, Monad m, Tv.Traversable col, ProcessHelper h) =>+    (forall sf. (b -> col sf -> col (ext, sf))) ->+    col (ProcessT m ext c) ->+    b -> m (h (col c), col (ProcessT m ext c))+parCore r sfs x =+  do+    let input = r x sfs+    ret <- Tv.sequenceA $ fmap app' input+    let zs = traverseResult $ fmap fst ret+        sfs' = fmap snd ret+    return (zs, sfs')+  where+    app' (y, sf) =+      do+        (hz, sf') <- step sf y+        return ((hz, suspend sf' y), sf')++pSwitch ::+    (Monad m, Tv.Traversable col) =>+    (forall sf. (b -> col sf -> col (ext, sf))) ->+    col (ProcessT m ext c) ->+    ProcessT m (b, col c) (Event mng) ->+    (col (ProcessT m ext c) -> mng -> ProcessT m b (col c)) ->+    ProcessT m b (col c)+pSwitch r sfs test =+    ggSwitch+        (\(CompositeStep _+            (CompositeStep (ParStep IDStep (PluralStep _ sfs')) _)) -> sfs')+        (CompositeStep (ArrStep (id &&& id))+            (CompositeStep (ParStep IDStep (PluralStep r sfs)) (arr snd &&& test)))++pSwitchB ::+    (Monad m, Tv.Traversable col) =>+    col (ProcessT m b c) ->+    ProcessT m (b, col c) (Event mng) ->+    (col (ProcessT m b c) -> mng -> ProcessT m b (col c)) ->+    ProcessT m b (col c)+pSwitchB = pSwitch broadcast++dpSwitch ::+    (Monad m, Tv.Traversable col) =>+    (forall sf. (b -> col sf -> col (ext, sf))) ->+    col (ProcessT m ext c) ->+    ProcessT m (b, col c) (Event mng) ->+    (col (ProcessT m ext c) -> mng -> ProcessT m b (col c)) ->+    ProcessT m b (col c)+dpSwitch r sfs test =+    dggSwitch+        (\(CompositeStep _+            (CompositeStep (ParStep IDStep (PluralStep _ sfs')) _)) -> sfs')+        (CompositeStep (ArrStep (id &&& id))+            (CompositeStep (ParStep IDStep (PluralStep r sfs)) (arr snd &&& test)))++dpSwitchB ::+    (Monad m, Tv.Traversable col) =>+    col (ProcessT m b c) ->+    ProcessT m (b, col c) (Event mng) ->+    (col (ProcessT m b c) -> mng -> ProcessT m b (col c)) ->+    ProcessT m b (col c)+dpSwitchB = dpSwitch broadcast++rpSwitch ::+    (Monad m, Tv.Traversable col) =>+    (forall sf. (b -> col sf -> col (ext, sf))) ->+    col (ProcessT m ext c) ->+    ProcessT m+        (b, Event (col (ProcessT m ext c) -> col (ProcessT m ext c)))+        (col c)+rpSwitch r sfs =+    ggSwitch+        (\(ParStep (PluralStep _ sfs') IDStep) -> sfs')+        (ParStep (PluralStep r sfs) IDStep)+        (\sfs' tr -> next r (tr sfs'))+  where+    next ::+        (Monad m, Tv.Traversable col) =>+        (forall sf. (b -> col sf -> col (ext, sf))) ->+        col (ProcessT m ext c) ->+        ProcessT m+            (b, Event (col (ProcessT m ext c) -> col (ProcessT m ext c)))+            (col c)+    next r' sfs' =+        dggSwitch+            (\(ParStep (PluralStep _ sfs'') IDStep) -> sfs'')+            (ParStep (PluralStep r' sfs') IDStep)+            (\sfs'' _ -> rpSwitch r' sfs'')+++rpSwitchB ::+    (Monad m, Tv.Traversable col) =>+    col (ProcessT m b c) ->+    ProcessT m+        (b, Event (col (ProcessT m b c) -> col (ProcessT m b c)))+        (col c)+rpSwitchB = rpSwitch broadcast+++drpSwitch ::+    (Monad m, Tv.Traversable col) =>+    (forall sf. (b -> col sf -> col (ext, sf))) ->+    col (ProcessT m ext c) ->+    ProcessT m+        (b, Event (col (ProcessT m ext c) -> col (ProcessT m ext c)))+        (col c)+drpSwitch r sfs =+    dggSwitch+        (\(ParStep (PluralStep _ sfs') IDStep) -> sfs')+        (ParStep (PluralStep r sfs) IDStep)+        (\sfs' tr -> drpSwitch r (tr sfs'))++drpSwitchB ::+    (Monad m, Tv.Traversable col) =>+    col (ProcessT m b c) ->+    ProcessT m+        (b, Event (col (ProcessT m b c) -> col (ProcessT m b c)))+        (col c)+drpSwitchB = drpSwitch broadcast+++--+-- Unsafe primitives+--++-- | Repeatedly call `p`.+--+-- How many times `p` is called is indefinite.+-- So `p` must satisfy the equation below;+--+-- @p &&& (p >>> arr null) === p &&& arr (const True)@+--+-- where+--+-- @null = getAll . foldMap (\_ -> All False)@+unsafeExhaust ::+    (Monad m, Fd.Foldable f) =>+    (b -> m (f c)) ->+    ProcessT m b (Event c)+unsafeExhaust p =+    go >>> fork+  where+    go = ProcessT {+        paFeed = \x -> do {y <- p x; return (Event y, go)},+        paSweep = \x -> do {y <- p x; return (if nullFd y then Nothing else Just (Event y), go)},+        paSuspend = const NoEvent+      }++    fork = repeatedly $ await >>= Fd.mapM_ yield++    nullFd = getAll . Fd.foldMap (\_ -> All False)+++--+-- Running+--++--+-- Running Monad (To be exported)+--+data RunInfo i o m = RunInfo {+    freezeRI :: !(ProcessT m i o),+    getInputRI :: !i,+    getPaddingRI :: !i,+    getPhaseRI :: !Phase+  }++type RM i o m = StateT (RunInfo i o m) m++runRM ::+    Monad m' =>+    ProcessT m (Event i) o ->+    StateT (RunInfo (Event i) o m) m' x ->+    m' x+runRM pa mx =+    evalStateT mx $+        RunInfo {+            freezeRI = pa,+            getInputRI = NoEvent,+            getPaddingRI = NoEvent,+            getPhaseRI = Sweep+          }++++feed_ ::+    (Monad m, MonadState (RunInfo i o m') m) =>+    i -> i -> m Bool+feed_ input padding =+  do+    ph <- gets getPhaseRI+    if ph == Suspend+        then+          do+            ri <- get+            put $ ri {+                getInputRI = input,+                getPaddingRI = padding,+                getPhaseRI = Feed+              }+            return True+        else+            return False++feedR ::+    (Monad m, MonadState (RunInfo (Event i) o m') m) =>+    i -> m Bool+feedR x = feed_ (Event x) NoEvent+++freeze ::+    Monad m =>+    RM i o m (ProcessT m i o)+freeze = gets freezeRI++sweepR ::+    Monad m =>+    RM i o m o+sweepR =+  do+    pa <- freeze+    ph <- gets getPhaseRI+    ri <- get+    case ph of+      Feed ->+        do+            x <- gets getInputRI+            (y, pa') <- lift $ feed pa x+            put $ ri {+                freezeRI = pa',+                getPhaseRI = Sweep+              }+            return y+      Sweep ->+        do+            x <- gets getPaddingRI+            (my, pa') <- lift $ sweep pa x+            put $ ri {+                freezeRI = pa',+                getPhaseRI = if isJust my then Sweep else Suspend+              }+            return $ fromMaybe (suspend pa x) my+      Suspend ->+        do+            x <- gets getPaddingRI+            return $ suspend pa x+++sweepAll ::+    (Monad m, Monad m') =>+    (forall p. RM i (Event o) m p -> m' p) ->+    (o -> m' ()) ->+    ContT Bool m' ()+sweepAll lft outpre =+    callCC $ \sus -> forever $ cond sus >> body+  where+    cond sus =+      do+        ph <- lift $ lft $ gets getPhaseRI+        if ph == Suspend then sus () else return ()+    body =+      do+        evx <- lift $ lft $ sweepR+        case evx+          of+            Event x ->+              do+                lift $ outpre x+            NoEvent ->+                return ()+            End ->+                breakCont False++breakCont :: Monad m => r -> ContT r m a+breakCont = ContT . const . return+++-- | Run a machine.+runT ::+    (Monad m, Fd.Foldable f) =>+    (c -> m ()) ->+    ProcessT m (Event b) (Event c) ->+    f b -> m ()+runT outpre0 pa0 xs =+    runRM pa0 $+      do+        _ <- evalContT $+          do+            -- Sweep initial events.+            sweepAll id outpre++            -- Feed values+            Fd.mapM_ feedSweep xs++            return True++        -- Terminate.+        _ <- feed_ End End+        _ <- evalContT $ sweepAll id outpre >> return True+        return ()+  where+    feedSweep x =+      do+        _ <- lift $ feedR x+        sweepAll id outpre++    outpre = lift . outpre0++type Builder b = F.F ((,) b)++putB :: b -> Builder b ()+putB x = F.liftF (x, ())++bToList :: Builder b a -> [b]+bToList x = build $ \cons nil -> F.runF x (const nil) (uncurry cons)++-- | Run a machine discarding all results.+runT_ ::+    (Monad m, Fd.Foldable f) =>+    ProcessT m (Event a) (Event b) ->+    f a -> m ()+runT_ pa l =+    runT (const $ return ()) pa l++run ::+    Fd.Foldable f =>+    ProcessT Identity (Event a) (Event b) ->+    f a -> [b]+run pa = bToList . runT putB (fit lift pa)++run_ ::+    (Fd.Foldable f, ArrowApply a) =>+    ProcessA a (Event b) (Event c) ->+    a (f b) ()+run_ pa = proc l -> case runT_ pa l of {ArrowMonad f -> f} -<< ()++lftRM :: (Monad m, Monad m') =>+    (forall p. m p -> m' p) ->+    RM i o m a ->+    StateT (RunInfo i o m) m' a+lftRM lft' st = StateT $ \s -> lft' $ runStateT st s+++-- | Execute until an input consumed and the machine suspends.+--+-- During the execution, the machine may yield values or stops.+-- It can be handled by two callbacks.+--+-- In some case the machine failed to consume the input value.+-- If so, the value is passed to the termination callback.+stepRun ::+    (Monad m, Monad m') =>+    (forall p. m p -> m' p) -- ^ Lifting function (pass `id` if m' ~ m)+      ->+    (b -> m' ()) -- ^ Callback on every output value.+      ->+    (Maybe a -> m' ()) -- ^ Callback on termination.+      ->+    ProcessT m (Event a) (Event b)  -- ^ The machine to run.+      ->+    a -- ^ The argument to the machine.+      ->+    m' (ProcessT m (Event a) (Event b))+stepRun lft yd stp pa0 x =+  do+    pa <- runRM pa0 $+      do+        csmd <- evalContT $+          do+            sweepAll (lftRM lft) (lift . yd)+            return True+        if csmd+          then do+            ct <- evalContT $+              do+                _ <- lift $ feedR x+                sweepAll (lftRM lft) (lift . yd)+                return True+            if ct+              then return ()+              else lift $ stp $ Nothing+          else+            lift $ stp $ Just x+        pa <- lftRM lft freeze+        return pa+    return pa+++-- | Execute until an output produced.+--+-- During the execution, the machine may await values or stops.+-- It can be handled by two callbacks.+--+-- If the machine stops without producing any value,+-- The first element of the return tuple is `Nothing`.+stepYield ::+    (Monad m, Monad m') =>+    (forall p. m p -> m' p)  -- ^ Lifting function (pass `id` if m' ~ m)+      ->+    m' a -- ^ Callback on input value request.+      ->+    m' () -- ^ Callback on termination+      ->+    ProcessT m (Event a) (Event b) -- ^ The machine to run.+      ->+    m' (Maybe b, ProcessT m (Event a) (Event b))+stepYield lft aw stp pa0 = runRM pa0 $+  do+    r <- go False+    pa <- lftRM lft freeze+    return (r, pa)++  where+    go csmd =+        lftRM lft sweepR >>= handleEv csmd++    handleEv _ (Event y) =+        return $ Just y++    handleEv True NoEvent =+        return Nothing++    handleEv False NoEvent =+      do+        x <- lift $ aw+        _ <- lftRM lft $ feedR x+        go True++    handleEv _ End =+        lift stp >> return Nothing
src/Control/Arrow/Machine/Utils.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE BangPatterns #-}  #if __GLASGOW_HASKELL__ >= 708 {-# LANGUAGE Safe #-}@@ -49,8 +50,8 @@         tee,         gather,         fork,-        filter,-        echo,+        fire,+        fire0,         anytime,         par,         parB,@@ -59,7 +60,7 @@         onEnd, #if defined(MIN_VERSION_arrows)         -- * Transformer-        readerProc+        -- readerProc #endif      ) where@@ -72,47 +73,88 @@ import Control.Monad.Trans import Control.Monad.State import Control.Arrow-import Control.Applicative #if defined(MIN_VERSION_arrows) import Control.Arrow.Transformer.Reader (ArrowAddReader(..)) #endif-import Control.Arrow.Machine.ArrowUtil+-- import Control.Arrow.Machine.ArrowUtil import Control.Arrow.Machine.Types -+-- $setup+-- >>> :set -XArrows    hold ::-    ArrowApply a => b -> ProcessA a (Event b) b+    Monad m => b -> ProcessT m (Event b) b hold old = proc evx ->   do     rSwitch (pure old) -< ((), pure <$> evx)  dHold ::-    ArrowApply a => b -> ProcessA a (Event b) b+    Monad m => b -> ProcessT m (Event b) b dHold old = proc evx ->   do     drSwitch (pure old) -< ((), pure <$> evx) +-- | Accumulate inputs like fold.+--+-- >>> :{+-- let pa = proc evx ->+--       do+--         val <- accum 0 -< (+1) <$ evx+--         returnA -< val <$ evx+--   in+--     run pa (replicate 10 ())+-- :}+-- [1,2,3,4,5,6,7,8,9,10]+--+-- Since 4.0.0, this function become strict for the first argument+-- because lazy one could rarely be used.+--+-- You can make `switch`es to make lazy one.+ accum ::-    ArrowApply a => b -> ProcessA a (Event (b->b)) b-accum x = switch (pure x &&& arr (($x)<$>)) accum'+    Monad m => b -> ProcessT m (Event (b->b)) b+accum !x = switch (pure x &&& arr (($x)<$>)) accum'   where     accum' y = dSwitch (pure y &&& Cat.id) (const (accum y)) +-- | Delayed version of `accum`.+--+-- >>> :{+-- let pa = proc evx ->+--       do+--         val <- dAccum 0 -< (+1) <$ evx+--         returnA -< val <$ evx+--   in+--     run pa (replicate 10 ())+-- :}+-- [0,1,2,3,4,5,6,7,8,9]+--+-- Since 4.0.0, this function become strict for the first argument+-- because lazy one could rarely be used.+--+-- You can make `switch`es to make lazy one.+ dAccum ::-    ArrowApply a => b -> ProcessA a (Event (b->b)) b-dAccum x = dSwitch (pure x &&& arr (($x)<$>)) dAccum+    Monad m => b -> ProcessT m (Event (b->b)) b+dAccum !x = dSwitch (pure x &&& arr (($x)<$>)) dAccum  +-- |Detects edges of input behaviour.+--+-- >>> run (hold 0 >>> edge) [1, 1, 2, 2, 2, 3]+-- [0,1,2,3]+--+-- >>> run (hold 0 >>> edge) [0, 1, 1, 2, 2, 2, 3]+-- [0,1,2,3] edge ::-    (ArrowApply a, Eq b) =>-    ProcessA a b (Event b)+    (Monad m, Eq b) =>+    ProcessT m b (Event b) edge = proc x ->   do     rec-        ev <- unsafeExhaust (arr judge) -< (prv, x)+        ev <- unsafeExhaust (return . judge) -< (prv, x)         prv <- dHold Nothing -< Just x <$ ev     returnA -< ev   where@@ -198,24 +240,24 @@ --   run (source [...] >>> af) (repeat ()) -- @ source ::-    (ArrowApply a, Fd.Foldable f) =>-    f c -> ProcessA a (Event b) (Event c)-source l = construct $ Fd.mapM_ yd l+    (Monad m, Fd.Foldable f) =>+    f a -> ProcessT m (Event i) (Event a)+source l = construct (Fd.mapM_ yd l)   where     yd x = await >> yield x  -- | Provides a blocking event stream. blockingSource ::-    (ArrowApply a, Fd.Foldable f) =>-    f c -> ProcessA a () (Event c)-blockingSource l = pure noEvent >>> construct (Fd.mapM_ yield l)+    (Monad m, Fd.Foldable f) =>+    f a -> ProcessT m ZeroEvent (Event a)+blockingSource l = arr collapse >>> construct (Fd.mapM_ yield l)  -- | Make a blocking source interleaved. interleave ::-    ArrowApply a =>-    ProcessA a () (Event c) ->-    ProcessA a (Event b) (Event c)-interleave bs0 = sweep1 (pure () >>> bs0)+    Monad m =>+    ProcessT m ZeroEvent (Event a) ->+    ProcessT m (Event i) (Event a)+interleave bs0 = sweep1 (mempty >>> bs0)   where     waiting bs r =         dSwitch@@ -231,7 +273,7 @@         ev' <- splitter bs r -< ev         returnA -< (filterJust (fst <$> ev'), snd <$> ev')     splitter bs r =-        construct $+        (arr collapse >>>) . construct $           do             _ <- await             yield (Just r, bs)@@ -240,9 +282,9 @@  -- | Make an interleaved source blocking. blocking ::-    ArrowApply a =>-    ProcessA a (Event ()) (Event c) ->-    ProcessA a () (Event c)+    Monad m =>+    ProcessT m (Event ()) (Event a) ->+    ProcessT m ZeroEvent (Event a) blocking is = dSwitch (blockingSource (repeat ()) >>> is >>> (Cat.id &&& onEnd)) (const stopped)  @@ -259,64 +301,91 @@ -- @... \<- gather -\< [Left \<$\> e1, Right \<$\> e2]@ -- tee ::-    ArrowApply a => ProcessA a (Event b1, Event b2) (Event (Either b1 b2))+    Monad m => ProcessT m (Event b1, Event b2) (Event (Either b1 b2)) tee = proc (e1, e2) -> gather -< [Left <$> e1, Right <$> e2]    -- |Make multiple event channels into one. -- If simultaneous events are given, lefter one is emitted earlier.+--+-- >>> :{+-- let pa = proc x ->+--       do+--         r1 <- filterEvent (\x -> x `mod` 2 == 0) -< x+--         r2 <- filterEvent (\x -> x `mod` 3 == 0) -< x+--         gather -< [r1, r2]+--   in+--     run pa [1..6]+-- :}+-- [2,3,4,6,6]+--+-- It is terminated when the last input finishes.+--+-- >>> :{+-- let pa = proc x ->+--       do+--         r1 <- filterEvent (\x -> x `mod` 3 == 0) -< x :: Event Int+--         r2 <- stopped -< x+--         r3 <- returnA -< r2+--         fin <- gather -< [r1, r2, r3]+--         val <- hold 0 -< r1+--         end <- onEnd -< fin+--         returnA -< val <$ end+--   in+--     run pa [1..5]+-- :}+-- [3]+ gather ::-    (ArrowApply a, Fd.Foldable f) =>-    ProcessA a (f (Event b)) (Event b)+    (Monad m, Fd.Foldable f) =>+    ProcessT m (f (Event b)) (Event b) gather = arr (Fd.foldMap $ fmap singleton) >>> fork   where     singleton x = x NonEmpty.:| []   -- |Given an array-valued event and emit it's values as inidvidual events.+--+-- >>> run fork [[1,2,3],[],[4,5]]+-- [1,2,3,4,5] fork ::-    (ArrowApply a, Fd.Foldable f) =>-    ProcessA a (Event (f b)) (Event b)+    (Monad m, Fd.Foldable f) =>+    ProcessT m (Event (f b)) (Event b)  fork = repeatedly $     await >>= Fd.mapM_ yield  -- |Executes an action once per an input event is provided.-anytime ::-    ArrowApply a =>-    a b c ->-    ProcessA a (Event b) (Event c)--anytime action = repeatedlyT (ary0 unArrowMonad) $-  do-    x <- await-    ret <- lift $ arrowMonad action x-    yield ret---filter ::-    ArrowApply a =>-    a b Bool ->-    ProcessA a (Event b) (Event b)-filter cond = repeatedlyT (ary0 unArrowMonad) $+fire ::+    Monad m =>+    (b -> m c) ->+    ProcessT m (Event b) (Event c)+fire fmy = repeatedlyT $   do     x <- await-    b <- lift $ arrowMonad cond x-    if b then yield x else return ()+    y <- lift $ fmy x+    yield y +-- |Executes an action once per an input event is provided.+fire0 ::+    Monad m =>+    m c ->+    ProcessT m (Event ()) (Event c)+fire0 = fire  . const -echo ::+-- |Executes an action once per an input event is provided.+anytime ::     ArrowApply a =>-    ProcessA a (Event b) (Event b)--echo = filter (arr (const True))+    a b c ->+    ProcessA a (Event b) (Event c)+anytime f = fire (\x -> ArrowMonad (arr (const x) >>> f))  -- |Emit an event of given value as soon as possible. oneshot ::-    ArrowApply a =>+    Monad m =>     c ->-    ProcessA a b (Event c)+    ProcessT m b (Event c) oneshot x = arr (const noEvent) >>> go   where     go = construct $@@ -328,14 +397,25 @@ --  now = oneshot () -- @ now ::-    ArrowApply a =>-    ProcessA a b (Event ())+    Monad m =>+    ProcessT m b (Event ()) now = oneshot ()  -- |Emit an event at the end of the input stream.+-- >>> :{+-- let+--     pa = proc evx ->+--       do+--         x <- hold 0 -< evx+--         ed <- onEnd -< evx+--         returnA -< x <$ ed+--   in+--     run pa [1..10]+-- :}+-- [10] onEnd ::-    (ArrowApply a, Occasional' b) =>-    ProcessA a b (Event ())+    (Monad m, Occasional' b) =>+    ProcessT m b (Event ()) onEnd = arr collapse >>> go   where     go = repeatedly $@@ -343,13 +423,15 @@   #if defined(MIN_VERSION_arrows)+{- -- | Run reader of base arrow. readerProc ::-    (ArrowApply a, ArrowApply a', ArrowAddReader r a a') =>-    ProcessA a b c ->-    ProcessA a' (b, r) c+    (Monad m, Monad m', ArrowAddReader r a a') =>+    ProcessT m b c ->+    ProcessT m' (b, r) c readerProc pa = arr swap >>> fitW snd (\ar -> arr swap >>> elimReader ar) pa   where     swap :: (a, b) -> (b, a)     swap ~(a, b) = (b, a)+-} #endif
+ test/Common/RandomProc.hs view
@@ -0,0 +1,212 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE Arrows #-}++module+    Common.RandomProc+where++import Prelude+import Control.Arrow.Machine as P+import Control.Arrow+import qualified Control.Category as Cat+import Control.Applicative+import Control.Monad+import Control.Monad.Trans+import Control.Monad.State+import Control.Monad.Writer+import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)+import Data.Maybe (fromJust)+import Data.Monoid (Sum(..), getSum, mappend)+import Data.Foldable (foldMap)+++data ProcJoin = PjFst ProcGen | PjSnd ProcGen | PjSum ProcGen+              deriving Show++data ProcGen = PgNop |+               PgStop |+               PgPush ProcGen |+               PgPop (ProcGen, ProcGen) ProcJoin |+               PgOdd ProcGen |+               PgDouble ProcGen |+               PgIncl ProcGen |+               PgHarf ProcGen+             deriving Show++instance+    Arbitrary ProcJoin+  where+    arbitrary = oneof [liftM PjFst arbitrary,+                      liftM PjSnd arbitrary,+                      liftM PjSum arbitrary]++instance+    Arbitrary ProcGen+  where+    arbitrary = sized $ \i ->+                frequency [(40, rest), (40 + i, content)]+      where+        rest = return PgNop+        content = oneof [+                   return PgNop,+                   return PgStop,+                   liftM PgPush arbitrary,+                   liftM2 PgPop arbitrary arbitrary,+                   liftM PgOdd arbitrary,+                   liftM PgDouble arbitrary,+                   liftM PgIncl arbitrary,+                   liftM PgHarf arbitrary+                  ]+type MyProcT = ProcessT (State [Int])++mkProc :: ProcGen+       -> MyProcT (Event Int) (Event Int)+++mkProc PgNop = Cat.id++mkProc (PgPush next) = mc >>> mkProc next+  where+    mc = repeatedlyT $+       do+         x <- await+         lift $ modify (\xs -> x:xs)+         yield x++mkProc (PgPop (fx, fy) fz) =+    mc >>> ((evMap fst >>> fork) &&& (evMap snd >>> fork))+       >>> (mkProc fx *** mkProc fy) >>> mkProcJ fz+  where+    mc = repeatedlyT $+       do+         x <- await+         ys <- lift $ get+         case ys+           of+             [] ->+                 yield (Just x, Nothing)+             (y:yss) ->+               do+                 lift $ put yss+                 yield (Just x, Just y)++mkProc (PgOdd next) = P.filterEvent cond >>> mkProc next+  where+    cond x = x `mod` 2 == 1++mkProc (PgDouble next) = arr (fmap $ \x -> [x, x]) >>> fork >>> mkProc next++mkProc (PgIncl next) = arr (fmap (+1)) >>> mkProc next++mkProc (PgHarf next) = arr (fmap (`div`2)) >>> mkProc next++mkProc (PgStop) = stopped++mkProcJ :: ProcJoin -> MyProcT (Event Int, Event Int) (Event Int)++mkProcJ (PjFst pg) = arr fst+mkProcJ (PjSnd pg) = arr snd+mkProcJ (PjSum pg) = proc (evx, evy) ->+    returnA -< getSum <$> foldMap (Sum <$>) [evx, evy]+++stateProc :: MyProcT (Event a) (Event b) -> [a] -> ([b], [Int])+stateProc pa i =+    runState (execWriterT $ runT (\x -> tell [x]) (fit lift pa) i) []++class+    TestIn a+  where+    input :: MyProcT (Event Int) a++class+    TestOut a+  where+    output :: MyProcT a (Event Int)++instance+    TestIn (Event Int)+  where+    input = Cat.id++instance+    TestOut (Event Int)+  where+    output = Cat.id++instance+    (TestIn a, TestIn b) => TestIn (a, b)+  where+    input = mc >>>+        ((evMap fst >>> fork >>> input) &&& (evMap snd >>> fork >>> input))+      where+        mc = repeatedly $+          do+            x <- await+            y <- await+            yield (Just x, Just y)++instance+    (TestOut a, TestOut b) => TestOut (a, b)+  where+    output = proc (x1, x2) ->+      do+        y1 <- output -< x1+        y2 <- output -< x2+        gather -< [y1, y2]++instance+    (TestIn a, TestIn b) =>+        TestIn (Either a b)+  where+    input = proc evx ->+      do+        -- 一個前の値で分岐してみる+        b <- dHold True -<+               (\x -> x `mod` 2 == 0) <$> evx++        if b+          then+            arr Left <<< input -< evx+          else+            arr Right <<< input -< evx++instance+    (TestOut a, TestOut b) => TestOut (Either a b)+  where+    output = output ||| output++type MyTestT a b = MyProcT a b -> MyProcT a b -> Bool++mkEquivTest :: (TestIn a, TestOut b) =>+               (Maybe (ProcGen, ProcJoin), ProcGen, ProcGen, [Int]) ->+               MyTestT a b+mkEquivTest (Nothing, pre, post, l) pa pb =+    let+        preA = mkProc pre+        postA = mkProc post+        mkCompared p = preA >>> input >>> p >>> output >>> postA+        x = stateProc (mkCompared pa) l+        y = stateProc (mkCompared pb) l+      in+        x == y++mkEquivTest (Just (par, j), pre, post, l) pa pb =+    let+        preA = mkProc pre+        postA = mkProc post+        parA = mkProc par+        joinA = mkProcJ j+        mkCompared p = preA >>> input >>> p >>> output >>> postA+        x = stateProc (mkCompared pa) l+        y = stateProc (mkCompared pb) l+      in+        x == y++mkEquivTest2 ::(Maybe (ProcGen, ProcJoin), ProcGen, ProcGen, [Int]) ->+               MyProcT (Event Int, Event Int) (Event Int, Event Int) ->+               MyProcT (Event Int, Event Int) (Event Int, Event Int) ->+               Bool+mkEquivTest2 = mkEquivTest+
− test/LoopUtil.hs
@@ -1,60 +0,0 @@-{-# LANGUAGE Arrows #-}--module-    LoopUtil-where--import Data.Functor-import Control.Arrow-import Test.Hspec--import Control.Category ((>>>))--import Control.Arrow.Machine as P-import Control.Monad.Trans (liftIO)-import qualified Control.Arrow.Machine.Misc.Pump as Pump--import Data.Monoid (Endo(Endo), mappend, appEndo)--newtype Duct a = Duct (Endo [a])--doubler = arr (fmap $ \x -> [x, x]) >>> P.fork--loopUtil =-  do-    describe "loop" $-      do-        it "is possible that value by `dHold` or `dAccum` can refer at upstream." $-          do-            let -                pa :: ProcessA (Kleisli IO) (Event Int) (Event Int)-                pa = proc evx ->-                  do-                    rec-                        anytime (Kleisli print) -< y <$ evx-                        anytime (Kleisli putStr) -< "" <$ evx -- side effect-                        evx2 <- doubler -< evx-                        y <- P.dAccum 0 -< (+) <$> evx2-                    returnA -< y <$ evx-            ret <- liftIO $ runKleisli (P.run pa) [1, 2, 3]-            ret `shouldBe` [0, 1+1, 1+1+2+2]-  -    describe "Pump" $-      do-        it "pumps up an event stream." $-          do-            let-                pa :: ProcessA (Kleisli IO) (Event Int) (Event Int)-                pa = proc evx ->-                  do-                    rec-                        evOut <- Pump.outlet -< (dct, () <$ evx)-                        anytime (Kleisli putStr) -< "" <$ evx -- side effect-                        so <- doubler -< evx-                        dct <- Pump.intake -< (so, () <$ evx)-                    returnA -< evOut--            ret <- liftIO $ runKleisli (P.run pa) [4, 5, 6]-            ret `shouldBe` [4, 4, 5, 5, 6, 6]--
+ test/Misc/PumpSpec.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE Arrows #-}++module+    Misc.PumpSpec+where++import Data.Functor+import Control.Arrow+import Test.Hspec++import Control.Category ((>>>))++import Control.Arrow.Machine as P+import Control.Monad.Trans (liftIO)+import qualified Control.Arrow.Machine.Misc.Pump as Pump++import Data.Monoid (Endo(Endo), mappend, appEndo)++import Data.IORef++newtype Duct a = Duct (Endo [a])++doubler = arr (fmap $ \x -> [x, x]) >>> P.fork++spec =+  do+    it "pumps up an event stream." $+      do+        ref <- newIORef ([] :: [Int])+        let+            pa :: ProcessT IO (Event Int) (Event ())+            pa = proc evx ->+              do+                rec+                    evOut <- Pump.outlet -< (dct, () <$ evx)+                    fire (putStr) -< "" <$ evx -- side effect+                    so <- doubler -< evx+                    dct <- Pump.intake -< (so, () <$ evx)+                fire (\x -> modifyIORef ref (x:)) -< evOut++        liftIO $ P.runT_ pa [4, 5, 6]+        ret <- readIORef ref+        reverse ret `shouldBe` [4, 4, 5, 5, 6, 6]++
− test/RandomProc.hs
@@ -1,221 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE Arrows #-}--module-    RandomProc-where--import Prelude-import Control.Arrow.Machine as P-import Control.Arrow-import qualified Control.Category as Cat-import Control.Applicative-import Control.Monad-import Control.Monad.Trans-import Control.Monad.State-import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)-import Data.Maybe (fromJust)-import Data.Monoid (Sum(..), getSum, mappend)-import Data.Foldable (foldMap)---data ProcJoin = PjFst ProcGen | PjSnd ProcGen | PjSum ProcGen-              deriving Show--data ProcGen = PgNop | -               PgStop |-               PgPush ProcGen |-               PgPop (ProcGen, ProcGen) ProcJoin |-               PgOdd ProcGen |-               PgDouble ProcGen |-               PgIncl ProcGen |-               PgHarf ProcGen-             deriving Show--instance-    Arbitrary ProcJoin-  where-    arbitrary = oneof [liftM PjFst arbitrary,-                      liftM PjSnd arbitrary,-                      liftM PjSum arbitrary]--instance -    Arbitrary ProcGen-  where-    arbitrary = sized $ \i ->-                frequency [(40, rest), (40 + i, content)]-      where-        rest = return PgNop-        content = oneof [-                   return PgNop, -                   return PgStop, -                   liftM PgPush arbitrary,-                   liftM2 PgPop arbitrary arbitrary,-                   liftM PgOdd arbitrary,-                   liftM PgDouble arbitrary,-                   liftM PgIncl arbitrary,-                   liftM PgHarf arbitrary-                  ]-type MyProcT = ProcessA (Kleisli (State [Int]))--mkProc :: ProcGen -       -> MyProcT (Event Int) (Event Int)---mkProc PgNop = Cat.id--mkProc (PgPush next) = mc >>> mkProc next-  where-    mc = repeatedlyT kleisli0 $-       do-         x <- await-         lift $ modify (\xs -> x:xs)-         yield x--mkProc (PgPop (fx, fy) fz) =-    mc >>> ((evMap fst >>> fork) &&& (evMap snd >>> fork))-       >>> (mkProc fx *** mkProc fy) >>> mkProcJ fz-  where-    mc = repeatedlyT kleisli0 $-       do-         x <- await-         ys <- lift $ get-         case ys -           of-             [] -> -                 yield (Just x, Nothing)-             (y:yss) -> -               do -                 lift $ put yss-                 yield (Just x, Just y)--mkProc (PgOdd next) = P.filter (arr cond) >>> mkProc next-  where-    cond x = x `mod` 2 == 1--mkProc (PgDouble next) = arr (fmap $ \x -> [x, x]) >>> fork >>> mkProc next--mkProc (PgIncl next) = arr (fmap (+1)) >>> mkProc next--mkProc (PgHarf next) = arr (fmap (`div`2)) >>> mkProc next--mkProc (PgStop) = stopped--mkProcJ :: ProcJoin -> MyProcT (Event Int, Event Int) (Event Int)--mkProcJ (PjFst pg) = arr fst-mkProcJ (PjSnd pg) = arr snd-mkProcJ (PjSum pg) = proc (evx, evy) ->-    returnA -< getSum <$> foldMap (Sum <$>) [evx, evy]---stateProc :: MyProcT (Event a) (Event b) -> [a] -> ([b], [Int])-stateProc a i = -    runState mx []-{--    unsafePerformIO $ -      do-        x <- timeout 10000 $-          do-            let x = runState mx []-            deepseq x $ return x-        return (fromJust x)--}-  where-    mx = runKleisli (run a) i--class -    TestIn a-  where-    input :: MyProcT (Event Int) a--class-    TestOut a-  where-    output :: MyProcT a (Event Int)--instance-    TestIn (Event Int)-  where-    input = Cat.id--instance-    TestOut (Event Int)-  where-    output = Cat.id--instance-    (TestIn a, TestIn b) => TestIn (a, b)-  where-    input = mc >>> -        ((evMap fst >>> fork >>> input) &&& (evMap snd >>> fork >>> input))-      where-        mc = repeatedly $-          do-            x <- await-            y <- await-            yield (Just x, Just y)--instance-    (TestOut a, TestOut b) => TestOut (a, b)-  where-    output = proc (x1, x2) ->-      do-        y1 <- output -< x1-        y2 <- output -< x2-        gather -< [y1, y2]--instance-    (TestIn a, TestIn b) => -        TestIn (Either a b)-  where-    input = proc evx ->-      do-        -- 一個前の値で分岐してみる-        b <- dHold True -< -               (\x -> x `mod` 2 == 0) <$> evx--        if b-          then-            arr Left <<< input -< evx-          else-            arr Right <<< input -< evx--instance-    (TestOut a, TestOut b) => TestOut (Either a b)-  where-    output = output ||| output--type MyTestT a b = MyProcT a b -> MyProcT a b -> Bool--mkEquivTest :: (TestIn a, TestOut b) =>-               (Maybe (ProcGen, ProcJoin), ProcGen, ProcGen, [Int]) ->-               MyTestT a b-mkEquivTest (Nothing, pre, post, l) pa pb =-    let-        preA = mkProc pre-        postA = mkProc post-        mkCompared p = preA >>> input >>> p >>> output >>> postA-        x = stateProc (mkCompared pa) l-        y = stateProc (mkCompared pb) l-      in-        x == y--mkEquivTest (Just (par, j), pre, post, l) pa pb =-    let-        preA = mkProc pre-        postA = mkProc post-        parA = mkProc par-        joinA = mkProcJ j-        mkCompared p = preA >>> input >>> p >>> output >>> postA-        x = stateProc (mkCompared pa) l-        y = stateProc (mkCompared pb) l-      in-        x == y--mkEquivTest2 ::(Maybe (ProcGen, ProcJoin), ProcGen, ProcGen, [Int]) ->-               MyProcT (Event Int, Event Int) (Event Int, Event Int) -> -               MyProcT (Event Int, Event Int) (Event Int, Event Int) ->-               Bool-mkEquivTest2 = mkEquivTest
+ test/Spec.hs view
@@ -0,0 +1,2 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}+
+ test/Types/BasicSpec.hs view
@@ -0,0 +1,111 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE FlexibleContexts #-}++module+    Types.BasicSpec+where++import qualified Control.Arrow.Machine as P++import Control.Arrow.Machine hiding (filter, source)+import Control.Applicative+import qualified Control.Category as Cat+import Control.Arrow+import Control.Monad.State+import Control.Monad+import Control.Monad.Trans+import Control.Monad.Identity (Identity, runIdentity)+import Debug.Trace+import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)++import Common.RandomProc+++spec =+  do+    it "is stream transducer." $+      do+        let+          process = repeatedly $+            do+              x <- await+              yield x+              yield (x + 1)++          resultA = run process [1,2,4]++        resultA `shouldBe` [1, 2, 2, 3, 4, 5]++    let+        -- 入力1度につき同じ値を2回出力する+        doubler = repeatedly $+                  do {x <- await; yield x; yield x}+        -- 入力値をStateのリストの先頭にPushする副作用を行い、同じ値を出力する+        pusher = repeatedlyT $+                 do {x <- await; lift $ modify (x:); yield x}++    it "has stop state" $+      let+          -- 一度だけ入力をそのまま出力し、すぐに停止する+          onlyOnce = construct $ await >>= yield++          x = stateProc (doubler >>> pusher >>> onlyOnce) [3, 3]+        in+          -- 最後尾のMachineが停止した時点で処理を停止するが、+          -- 既にa2が出力した値の副作用は処理する+          x `shouldBe` ([3], [3, 3])++    it "has side-effect" $+      let+          incl = evMap (+1)++          -- doublerで信号が2つに分岐する。+          -- このとき、副作用は1つ目の信号について末尾まで+          -- -> 二つ目の信号について分岐点から末尾まで ...+          -- の順で処理される。+          a = pusher >>> doubler >>> incl >>> pusher >>> incl >>> pusher++          x = stateProc a [1000]+        in+          x `shouldBe` ([1002, 1002], reverse [1000,1001,1002,1001,1002])++    it "never spoils any FEED" $+      let+          counter = construct $ counterDo 1+          counterDo n =+            do+              x <- await+              yield $ n * 100 + x+              counterDo (n+1)+          x = stateProc (doubler >>> doubler >>> counter) [1,2]+        in+          fst x `shouldBe` [101, 201, 301, 401, 502, 602, 702, 802]++    prop "each path can have independent number of events" $ \l ->+      let+          split2' = fmap fst &&& fmap snd+          gen = arr (fmap $ \x -> [x, x]) >>> fork >>> arr split2'+          r1 = run (gen >>> arr fst) (l::[(Int, [Int])])+          r2 = run (gen >>> second (fork >>> repeatedly (await >>= yield)) >>> arr fst)+               (l::[(Int, [Int])])+        in+          r1 == r2++    it "is lazy for individual input values" $+      do+        let l = run Cat.id (take 10 $ repeat undefined)+        length l `shouldBe` 10++{-+    it "is lazy for inpurt stream" $+      do+        let l = take 10 $ run Cat.id (repeat undefined)+        length l `shouldBe` 10+-}
+ test/Types/ChoiceSpec.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE FlexibleContexts #-}++module+    Types.ChoiceSpec+where++import qualified Control.Arrow.Machine as P++import Control.Arrow.Machine hiding (filter, source)+import Control.Applicative+import qualified Control.Category as Cat+import Control.Arrow+import Control.Monad.State+import Control.Monad+import Control.Monad.Trans+import Control.Monad.Identity (Identity, runIdentity)+import Debug.Trace+import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)++import Common.RandomProc+++spec =+  do+    it "temp1" $+     do+       let+            af = mkProc $ PgStop+            ag = mkProc $ PgOdd PgNop+            aj1 = arr Right+            aj2 = arr $ either id id+            l = [1]+            r1 = stateProc+                   (aj1 >>> left af >>> aj2)+                   l+          in+            r1 `shouldBe` ([1],[])++    prop "left (f >>> g) = left f >>> left g" $ \fx gx cond ->+        let+            f = mkProc fx+            g = mkProc gx++            equiv = mkEquivTest cond+                ::(MyTestT (Either (Event Int) (Event Int))+                           (Either (Event Int) (Event Int)))+          in+            (left (f >>> g)) `equiv` (left f >>> left g)+
+ test/Types/LoopSpec.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE Arrows #-}++module+    Types.LoopSpec+where++import Data.Functor+import Control.Arrow+import Test.Hspec++import Control.Arrow.Machine as P+import Control.Monad.Trans (liftIO)++import Data.IORef++import Common.RandomProc++doubler = arr (fmap $ \x -> [x, x]) >>> P.fork++spec =+  do+    it "is possible that value by `dHold` or `dAccum` can refer at upstream." $+      do+        ref <- newIORef ([] :: [Int])+        let+            pa :: ProcessT IO (Event Int) (Event ())+            pa = proc evx ->+              do+                rec+                    P.fire print -< y <$ evx+                    P.fire putStr -< "" <$ evx -- side effect+                    evx2 <- doubler -< evx+                    y <- P.dAccum 0 -< (+) <$> evx2+                fire (\x -> modifyIORef ref (x:)) -<  y <$ evx++        liftIO $ P.runT_ pa [1, 2, 3]+        ret <- readIORef ref+        reverse ret `shouldBe` [0, 1+1, 1+1+2+2]++    it "can be used with rec statement(pure)" $+      let+          a = proc ev ->+            do+              x <- hold 0 -< ev+              rec l <- returnA -< x:l+              returnA -< l <$ ev+          result = fst $ stateProc a [2, 5]+        in+          take 3 (result!!1) `shouldBe` [5, 5, 5]++    it "the last value is valid." $+      do+        let+            mc = repeatedly $+              do+                x <- await+                yield x+                yield (x*2)+            pa = proc x ->+              do+                rec y <- mc -< (+z) <$> x+                    z <- dHold 0 -< y+                returnA -< y+        run pa [1, 10] `shouldBe` [1, 2, 12, 24]++    it "carries no events to upstream." $+      do+        let+            pa = proc ev ->+              do+                rec r <- dHold True -< False <$ ev2+                    ev2 <- fork -< [(), ()] <$ ev+                returnA -< r <$ ev+        run pa [1, 2, 3] `shouldBe` [True, True, True]+
+ test/Types/PlanSpec.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE FlexibleContexts #-}++module+    Types.PlanSpec+where++import qualified Control.Arrow.Machine as P++import Control.Arrow.Machine hiding (filter, source)+import Control.Applicative+import qualified Control.Category as Cat+import Control.Arrow+import Control.Monad.State+import Control.Monad+import Control.Monad.Trans+import Control.Monad.Identity (Identity, runIdentity)+import Debug.Trace+import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)++import Common.RandomProc+++spec =+  do+    let pl =+          do+            x <- await+            yield x+            yield (x+1)+            x <- await+            yield x+            yield (x+1)+        l = [2, 5, 10, 20, 100]++    it "can be constructed into ProcessA" $+      do+        let+            result = run (construct pl) l+        result `shouldBe` [2, 3, 5, 6]++    it "can be repeatedly constructed into ProcessA" $+      do+        let+            result = run (repeatedly pl) l+        result `shouldBe` [2, 3, 5, 6, 10, 11, 20, 21, 100, 101]++    it "can handle the end with catchP." $+      do+        let+            plCatch =+              do+                x <- await `catchP` (yield 1 >> stop)+                yield x+                y <- (yield 2 >> await >> yield 3 >> await) `catchP` (yield 4 >> return 5)+                yield y+                y <- (await >>= yield >> stop) `catchP` (yield 6 >> return 7)+                yield y+        run (construct plCatch) [] `shouldBe` [1]+        run (construct plCatch) [100] `shouldBe` [100, 2, 4, 5, 6, 7]+        run (construct plCatch) [100, 200] `shouldBe` [100, 2, 3, 4, 5, 6, 7]+        run (construct plCatch) [100, 200, 300] `shouldBe` [100, 2, 3, 300, 6, 7]+        run (construct plCatch) [100, 200, 300, 400] `shouldBe` [100, 2, 3, 300, 400, 6, 7]
+ test/Types/RuleSpec.hs view
@@ -0,0 +1,155 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE FlexibleContexts #-}++module+Types.RuleSpec+where++import qualified Control.Arrow.Machine as P++import Control.Arrow.Machine hiding (filter, source)+import Control.Applicative+import qualified Control.Category as Cat+import Control.Arrow+import Control.Monad.State+import Control.Monad+import Control.Monad.Trans+import Control.Monad.Identity (Identity, runIdentity)+import Debug.Trace+import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)++import Common.RandomProc+++spec =+  do+    describe "ProcessA as Category" $ catSpec+    describe "ProcessA as Arrow" $ arrSpec+    describe "Rules for ArrowLoop" $ arrowLoopSpec++catSpec =+  do+    prop "has asocciative composition" $ \fx gx hx cond ->+      let+          f = mkProc fx+          g = mkProc gx+          h = mkProc hx+          equiv = mkEquivTest cond+        in+          ((f >>> g) >>> h) `equiv` (f >>> (g >>> h))++    prop "has identity" $ \fx gx cond ->+      let+          f = mkProc fx+          g = mkProc gx+          equiv = mkEquivTest cond+        in+          (f >>> g) `equiv` (f >>> Cat.id >>> g)++arrSpec =+  do+    it "can be made from pure function(arr)" $+      do+        (run . arr . fmap $ (+ 2)) [1, 2, 3]+          `shouldBe` [3, 4, 5]++    prop "arr id is identity" $ \fx gx cond ->+      let+          f = mkProc fx+          g = mkProc gx+          equiv = mkEquivTest cond+        in+          (f >>> g) `equiv` (f >>> arr id >>> g)++    it "can be parallelized" $+      do+        pendingWith "to correct"+{-+        let+            myProc2 = repeatedlyT (Kleisli . const) $+              do+                x <- await+                lift $ modify (++ [x])+                yield `mapM` (take x $ repeat x)++            toN = evMaybe Nothing Just+            en (ex, ey) = Event (toN ex, toN ey)+            de evxy = (fst <$> evxy, snd <$> evxy)++            l = map (\x->(x,x)) [1,2,3]++            (result, state) =+                stateProc (arr de >>> first myProc2 >>> arr en) l++        (result >>= maybe mzero return . fst)+            `shouldBe` [1,2,2,3,3,3]+        (result >>= maybe mzero return . snd)+            `shouldBe` [1,2,3]+        state `shouldBe` [1,2,3]+-}++    prop "first and composition." $ \fx gx cond ->+      let+          f = mkProc fx+          g = mkProc gx+          equiv = mkEquivTest2 cond+        in+          (first (f >>> g)) `equiv` (first f >>> first g)++    prop "first-second commutes" $  \fx cond ->+      let+          f = first $ mkProc fx+          g = second (arr $ fmap (+2))++          equiv = mkEquivTest2 cond+        in+          (f >>> g) `equiv` (g >>> f)++    prop "first-fst commutes" $  \fx cond ->+      let+          f = mkProc fx+          equiv = mkEquivTest cond+                ::(MyTestT (Event Int, Event Int) (Event Int))+        in+          (first f >>> arr fst) `equiv` (arr fst >>> f)++    prop "assoc relation" $ \fx cond ->+      let+          f = mkProc fx+          assoc ((a,b),c) = (a,(b,c))++          equiv = mkEquivTest cond+                ::(MyTestT ((Event Int, Event Int), Event Int)+                           (Event Int, (Event Int, Event Int)))+        in+          (first (first f) >>> arr assoc) `equiv` (arr assoc >>> first f)++arrowLoopSpec =+  do+    let+        fixcore f y = if y `mod` 5 == 0 then y else y + f (y-1)+        pure (evx, f) = (f <$> evx, fixcore f)+        apure = arr pure++    prop "left tightening" $ \fx cond ->+      let+          f = mkProc fx++          equiv = mkEquivTest cond+        in+          (loop (first f >>> apure)) `equiv` (f >>> loop apure)++    prop "right tightening" $ \fx cond ->+      let+          f = mkProc fx++          equiv = mkEquivTest cond+        in+          (loop (apure >>> first f)) `equiv` (loop apure >>> f)
+ test/Types/StepExecutionSpec.hs view
@@ -0,0 +1,192 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NamedFieldPuns #-}++module+    Types.StepExecutionSpec+where++import qualified Control.Arrow.Machine as P++import Data.Maybe (isJust)+import Control.Arrow.Machine hiding (filter, source)+import Control.Applicative+import qualified Control.Category as Cat+import Control.Arrow+import Control.Monad.State+import Control.Monad+import Control.Monad.Trans+import Control.Monad.Identity (Identity, runIdentity)+import Debug.Trace+import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)++import Common.RandomProc++-- | Represents return values and informations of step executions.+data ExecInfo a =+    ExecInfo+      {+        yields :: [a], -- ^ Values yielded while the step.+        hasConsumed :: Bool, -- ^ True if the input value is consumed.+            --+            -- False if the machine has stopped unless consuming the input.+            --+            -- Or in the case of `stepYield`, this field become false when+            -- the machine produces a value unless consuming the input.+        hasStopped :: Bool -- ^ True if the machine has stopped at the end of the step.+      }+    deriving (Eq, Show)+++spec =+  do+    it "supports step execution" $+      do+        let+            pl =+              do+                x <- await+                yield x+                yield (x+1)+                x <- await+                yield x+                yield (x+1)+                yield (x+5)+            init = construct pl++            pl2 =+              do+                _ <- await+                return ()+            init2 = construct pl2++            emptyEI = ExecInfo+              {+                yields = [],+                hasConsumed = True, -- Set False if there's any leftover+                hasStopped = False+              }++            onYield x =+                modify $ \ei@ExecInfo{yields = xs} -> ei {yields = xs ++ [x]}++            onStop ma =+                modify $ \ei -> ei {hasConsumed = not (isJust ma), hasStopped = True}++        -- execution part+        --   x <- await+        --   yield x+        --   yield (x+1)+        (now, ret) <- runStateT (stepRun lift onYield onStop init 1) emptyEI+        yields ret `shouldBe` [1, 2]+        hasConsumed ret `shouldBe` True+        hasStopped ret `shouldBe` False++        -- execution part+        --   x <- await+        --   yield x+        --   yield (x+1)+        --   yield (x+5)+        (now, ret) <- runStateT (stepRun lift onYield onStop now 1) emptyEI+        yields ret `shouldBe` [1, 2, 6]+        hasConsumed ret `shouldBe` True+        hasStopped ret `shouldBe` True++        -- no execution part is left+        (now, ret) <- runStateT (stepRun lift onYield onStop now 1) emptyEI+        yields ret `shouldBe` ([]::[Int])+        hasConsumed ret `shouldBe` False+        hasStopped ret `shouldBe` True++        -- execution part+        --   _ <- await+        --   return ()+        (now, ret) <- runStateT (stepRun lift onYield onStop init2 1) emptyEI+        yields ret `shouldBe` ([]::[Int])+        hasConsumed ret `shouldBe` True+        hasStopped ret `shouldBe` True++    it "supports yield-driven step" $+      do+        let+            init = construct $+              do+                yield (-1)+                _ <- await+                x <- await+                mapM yield (iterate (+1) x) -- infinite+            init2 = construct $+              do+                return ()+            init3 = construct $+              do+                _ <- await+                return ()++            emptyEI = ExecInfo+              {+                yields = [], -- Not used+                hasConsumed = False,+                hasStopped = False+              }++            provide x =+              do+                modify $ \ei -> ei {hasConsumed = True}+                return x++            onStop =+                modify $ \ei -> ei {hasStopped = True}++        -- execution part+        --   yield (-1)+        ((val, now), ret) <- runStateT (stepYield lift (provide 5) onStop init) emptyEI+        val `shouldBe` Just (-1)+        hasConsumed ret `shouldBe` False+        hasStopped ret `shouldBe` False++        -- execution part+        --   _ <- await+        ((val, now), ret) <- runStateT (stepYield lift (provide 6) onStop now) emptyEI+        val `shouldBe` Nothing+        hasConsumed ret `shouldBe` True+        hasStopped ret `shouldBe` False++        -- execution part+        --   x <- await+        --   mapM yield (iterate (+1) x) -- first one+        ((val, now), ret) <- runStateT (stepYield lift (provide 10) onStop now) emptyEI+        val `shouldBe` Just 10+        hasConsumed ret `shouldBe` True+        hasStopped ret `shouldBe` False++        -- execution part+        --   mapM yield (iterate (+1) x) -- second one+        ((val, now), ret) <- runStateT (stepYield lift (provide 10) onStop now) emptyEI+        val `shouldBe` Just 11+        hasConsumed ret `shouldBe` False+        hasStopped ret `shouldBe` False++        -- execution part+        --   return ()+        ((val, now), ret) <- runStateT (stepYield lift (provide 0) onStop init2) emptyEI+        val `shouldBe` (Nothing :: Maybe Int)+        hasConsumed ret `shouldBe` False+        hasStopped ret `shouldBe` True++        -- execution part+        --   _ <- await+        --   return ()+        ((val, now), ret) <- runStateT (stepYield lift (provide 0) onStop init3) emptyEI+        val `shouldBe` (Nothing :: Maybe Int)+        hasConsumed ret `shouldBe` True+        hasStopped ret `shouldBe` True++
+ test/Types/SwitchSpec.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE FlexibleContexts #-}++module+    Types.SwitchSpec+where++import Data.Maybe (fromMaybe)+import qualified Control.Arrow.Machine as P+import Control.Arrow.Machine hiding (filter, source)+import Control.Applicative+import qualified Control.Category as Cat+import Control.Arrow+import Control.Monad.State+import Control.Monad+import Control.Monad.Trans+import Control.Monad.Identity (Identity, runIdentity)+import Debug.Trace+import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)++import Common.RandomProc+++spec =+  do+    describe "kSwitch" $+      do+        it "switches spontaneously" $+          do+            let+                theArrow sw = sw (oneshot False) (arr snd) $ \_ _ -> oneshot True+            run (theArrow kSwitch) [] `shouldBe` [True]+            run (theArrow dkSwitch) [] `shouldBe` [False, True]
+ test/Utils/SourceSpec.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE FlexibleContexts #-}++module+    Utils.SourceSpec+where++import Data.Maybe (fromMaybe)+import qualified Control.Arrow.Machine as P+import Control.Arrow.Machine hiding (filter, source)+import Control.Applicative+import qualified Control.Category as Cat+import Control.Arrow+import Control.Monad.State+import Control.Monad+import Control.Monad.Trans+import Control.Monad.Identity (Identity, runIdentity)+import Debug.Trace+import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)++import Common.RandomProc++spec =+  do+    describe "source" $+      do+        it "provides interleaved source stream" $+          do+            let+                pa = proc cl ->+                  do+                    s1 <- P.source [1, 2, 3] -< cl+                    s2 <- P.source [4, 5, 6] -< cl+                    P.gather -< [s1, s2]+            P.run pa (repeat ()) `shouldBe` [1, 4, 2, 5, 3, 6]+    describe "blockingSource" $+      do+        it "provides blocking source stream" $+          do+            let+                pa = proc _ ->+                  do+                    s1 <- P.blockingSource [1, 2, 3] -< mempty+                    s2 <- P.blockingSource [4, 5, 6] -< mempty+                    P.gather -< [s1, s2]+            P.run pa (repeat ()) `shouldBe` [4, 5, 6, 1, 2, 3]++    describe "source and blockingSource" $+      do+        prop "[interleave blockingSource = source]" $ \l cond ->+            let+                _ = l::[Int]+                equiv = mkEquivTest cond+                    ::(MyTestT (Event Int) (Event Int))+              in+                P.source l `equiv` P.interleave (P.blockingSource l)++        prop "[blocking source = blockingSource]" $ \l cond ->+            let+                _ = l::[Int]+                equiv = mkEquivTest cond+                    ::(MyTestT (Event Int) (Event Int))+              in+                (mempty >>> P.blockingSource l)+                    `equiv` (mempty >>> P.blocking (P.source l))++
+ test/doctest.hs view
@@ -0,0 +1,8 @@+module Main where++import Test.DocTest++main :: IO ()+main = doctest ["src"]++
− test/spec.hs
@@ -1,596 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE Arrows #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoMonomorphismRestriction #-}-{-# LANGUAGE FlexibleContexts #-}--module-    Main-where--import Data.Maybe (fromMaybe)-import qualified Control.Arrow.Machine as P-import Control.Arrow.Machine hiding (filter, source)-import Control.Applicative-import qualified Control.Category as Cat-import Control.Arrow-import Control.Monad.State-import Control.Monad-import Control.Monad.Trans-import Control.Monad.Identity (Identity, runIdentity)-import Debug.Trace-import Test.Hspec-import Test.Hspec.QuickCheck (prop)-import Test.QuickCheck (Arbitrary, arbitrary, oneof, frequency, sized)-import RandomProc-import LoopUtil-runKI a x = runIdentity (runKleisli a x)----main = hspec $-  do-    basics-    rules-    loops-    choice-    plans-    utility-    switches-    source-    execution-    loopUtil---basics =-  do-    describe "ProcessA" $-      do-        it "is stream transducer." $-          do-            let-              process = repeatedly $-                do-                  x <- await-                  yield x-                  yield (x + 1)--              resultA = run process [1,2,4]--            resultA `shouldBe` [1, 2, 2, 3, 4, 5]--        let-            -- 入力1度につき同じ値を2回出力する-            doubler = repeatedly $-                      do {x <- await; yield x; yield x}-            -- 入力値をStateのリストの先頭にPushする副作用を行い、同じ値を出力する-            pusher = repeatedlyT (Kleisli . const) $-                     do {x <- await; lift $ modify (x:); yield x}--        it "has stop state" $-          let-              -- 一度だけ入力をそのまま出力し、すぐに停止する-              onlyOnce = construct $ await >>= yield--              x = stateProc (doubler >>> pusher >>> onlyOnce) [3, 3]-            in-              -- 最後尾のMachineが停止した時点で処理を停止するが、-              -- 既にa2が出力した値の副作用は処理する-              x `shouldBe` ([3], [3, 3])--        it "has side-effect" $-          let-              incl = arr $ fmap (+1)--              -- doublerで信号が2つに分岐する。-              -- このとき、副作用は1つ目の信号について末尾まで-              -- -> 二つ目の信号について分岐点から末尾まで ...-              -- の順で処理される。-              a = pusher >>> doubler >>> incl >>> pusher >>> incl >>> pusher--              x = stateProc a [1000]-            in-              x `shouldBe` ([1002, 1002], reverse [1000,1001,1002,1001,1002])--        it "never spoils any FEED" $-          let-              counter = construct $ counterDo 1-              counterDo n =-                do-                  x <- await-                  yield $ n * 100 + x-                  counterDo (n+1)-              x = stateProc (doubler >>> doubler >>> counter) [1,2]-            in-              fst x `shouldBe` [101, 201, 301, 401, 502, 602, 702, 802]--        prop "each path can have independent number of events" $ \l ->-          let-              split2' = fmap fst &&& fmap snd-              gen = arr (fmap $ \x -> [x, x]) >>> fork >>> arr split2'-              r1 = runKI (run (gen >>> arr fst)) (l::[(Int, [Int])])-              r2 = runKI (run (gen >>> second (fork >>> echo) >>> arr fst))-                   (l::[(Int, [Int])])-            in-              r1 == r2--        it "is lazy for individual input values" $-          do-            let l = runOn (\x -> [x]) Cat.id (take 10 $ repeat undefined)-            length l `shouldBe` 10--{--        it "is lazy for inpurt stream" $-          do-            let l = take 10 $ run Cat.id (repeat undefined)-            length l `shouldBe` 10--}--rules =-  do-    describe "ProcessA as Category" $-      do-        prop "has asocciative composition" $ \fx gx hx cond ->-          let-              f = mkProc fx-              g = mkProc gx-              h = mkProc hx-              equiv = mkEquivTest cond-            in-              ((f >>> g) >>> h) `equiv` (f >>> (g >>> h))--        prop "has identity" $ \fx gx cond ->-          let-              f = mkProc fx-              g = mkProc gx-              equiv = mkEquivTest cond-            in-              (f >>> g) `equiv` (f >>> Cat.id >>> g)--    describe "ProcessA as Arrow" $-      do-        it "can be made from pure function(arr)" $-          do-            (run . arr . fmap $ (+ 2)) [1, 2, 3]-              `shouldBe` [3, 4, 5]--        prop "arr id is identity" $ \fx gx cond ->-          let-              f = mkProc fx-              g = mkProc gx-              equiv = mkEquivTest cond-            in-              (f >>> g) `equiv` (f >>> arr id >>> g)--        it "can be parallelized" $-          do-            pendingWith "to correct"-{--            let-                myProc2 = repeatedlyT (Kleisli . const) $-                  do-                    x <- await-                    lift $ modify (++ [x])-                    yield `mapM` (take x $ repeat x)--                toN = evMaybe Nothing Just-                en (ex, ey) = Event (toN ex, toN ey)-                de evxy = (fst <$> evxy, snd <$> evxy)--                l = map (\x->(x,x)) [1,2,3]--                (result, state) =-                    stateProc (arr de >>> first myProc2 >>> arr en) l--            (result >>= maybe mzero return . fst)-                `shouldBe` [1,2,2,3,3,3]-            (result >>= maybe mzero return . snd)-                `shouldBe` [1,2,3]-            state `shouldBe` [1,2,3]--}--        prop "first and composition." $ \fx gx cond ->-          let-              f = mkProc fx-              g = mkProc gx-              equiv = mkEquivTest2 cond-            in-              (first (f >>> g)) `equiv` (first f >>> first g)--        prop "first-second commutes" $  \fx cond ->-          let-              f = first $ mkProc fx-              g = second (arr $ fmap (+2))--              equiv = mkEquivTest2 cond-            in-              (f >>> g) `equiv` (g >>> f)--        prop "first-fst commutes" $  \fx cond ->-          let-              f = mkProc fx-              equiv = mkEquivTest cond-                    ::(MyTestT (Event Int, Event Int) (Event Int))-            in-              (first f >>> arr fst) `equiv` (arr fst >>> f)--        prop "assoc relation" $ \fx cond ->-          let-              f = mkProc fx-              assoc ((a,b),c) = (a,(b,c))--              equiv = mkEquivTest cond-                    ::(MyTestT ((Event Int, Event Int), Event Int)-                               (Event Int, (Event Int, Event Int)))-            in-              (first (first f) >>> arr assoc) `equiv` (arr assoc >>> first f)--loops =-  do-    describe "ProcessA as ArrowLoop" $-      do-        it "can be used with rec statement(pure)" $-          let-              a = proc ev ->-                do-                  x <- hold 0 -< ev-                  rec l <- returnA -< x:l-                  returnA -< l <$ ev-              result = fst $ stateProc a [2, 5]-            in-              take 3 (result!!1) `shouldBe` [5, 5, 5]--        it "the last value is valid." $-          do-            let-                mc = repeatedly $-                  do-                    x <- await-                    yield x-                    yield (x*2)-                pa = proc x ->-                  do-                    rec y <- mc -< (+z) <$> x-                        z <- dHold 0 -< y-                    returnA -< y-            run pa [1, 10] `shouldBe` [1, 2, 12, 24]--        it "carries no events to upstream." $-          do-            let-                pa = proc ev ->-                  do-                    rec r <- dHold True -< False <$ ev2-                        ev2 <- fork -< [(), ()] <$ ev-                    returnA -< r <$ ev-            run pa [1, 2, 3] `shouldBe` [True, True, True]---    describe "Rules for ArrowLoop" $-      do-        let-            fixcore f y = if y `mod` 5 == 0 then y else y + f (y-1)-            pure (evx, f) = (f <$> evx, fixcore f)-            apure = arr pure--        prop "left tightening" $ \fx cond ->-          let-              f = mkProc fx--              equiv = mkEquivTest cond-            in-              (loop (first f >>> apure)) `equiv` (f >>> loop apure)--        prop "right tightening" $ \fx cond ->-          let-              f = mkProc fx--              equiv = mkEquivTest cond-            in-              (loop (apure >>> first f)) `equiv` (loop apure >>> f)---choice =-  do-    describe "ProcessA as ArrowChoice" $-      do-        it "temp1" $-         do-           let-                af = mkProc $ PgStop-                ag = mkProc $ PgOdd PgNop-                aj1 = arr Right-                aj2 = arr $ either id id-                l = [1]-                r1 = stateProc-                       (aj1 >>> left af >>> aj2)-                       l-              in-                r1 `shouldBe` ([1],[])--        prop "left (f >>> g) = left f >>> left g" $ \fx gx cond ->-            let-                f = mkProc fx-                g = mkProc gx--                equiv = mkEquivTest cond-                    ::(MyTestT (Either (Event Int) (Event Int))-                               (Either (Event Int) (Event Int)))-              in-                (left (f >>> g)) `equiv` (left f >>> left g)---plans = describe "Plan" $-  do-    let pl =-          do-            x <- await-            yield x-            yield (x+1)-            x <- await-            yield x-            yield (x+1)-        l = [2, 5, 10, 20, 100]--    it "can be constructed into ProcessA" $-      do-        let-            result = run (construct pl) l-        result `shouldBe` [2, 3, 5, 6]--    it "can be repeatedly constructed into ProcessA" $-      do-        let-            result = run (repeatedly pl) l-        result `shouldBe` [2, 3, 5, 6, 10, 11, 20, 21, 100, 101]--    it "can handle the end with catchP." $-      do-        let-            plCatch =-              do-                x <- await `catchP` (yield 1 >> stop)-                yield x-                y <- (yield 2 >> await >> yield 3 >> await) `catchP` (yield 4 >> return 5)-                yield y-                y <- (await >>= yield >> stop) `catchP` (yield 6 >> return 7)-                yield y-        run (construct plCatch) [] `shouldBe` [1]-        run (construct plCatch) [100] `shouldBe` [100, 2, 4, 5, 6, 7]-        run (construct plCatch) [100, 200] `shouldBe` [100, 2, 3, 4, 5, 6, 7]-        run (construct plCatch) [100, 200, 300] `shouldBe` [100, 2, 3, 300, 6, 7]-        run (construct plCatch) [100, 200, 300, 400] `shouldBe` [100, 2, 3, 300, 400, 6, 7]--utility =-  do-    describe "splitEvent" $-      do-        it "splits an event stream" $-          do-            run (splitEvent >>> arr fst) [Left 1, Right 2, Left 3, Right 4] `shouldBe` [1, 3]-            run (splitEvent >>> arr snd) [Left 1, Right 2, Left 3, Right 4] `shouldBe` [2, 4]--    describe "edge" $-      do-        it "detects edges of input behaviour" $-          do-            run (hold 0 >>> edge) [1, 1, 2, 2, 2, 3] `shouldBe` [0, 1, 2, 3]-            run (hold 0 >>> edge) [0, 1, 1, 2, 2, 2, 3] `shouldBe` [0, 1, 2, 3]--    describe "accum" $-      do-        it "acts like fold." $-          do-            let-                pa = proc evx ->-                  do-                    val <- accum 0 -< (+1) <$ evx-                    returnA -< val <$ evx--            run pa (replicate 10 ()) `shouldBe` [1..10]--    describe "onEnd" $-      do-        it "fires only once at the end of a stream." $-          do-            let-                pa = proc evx ->-                  do-                    x <- hold 0 -< evx-                    ed <- onEnd -< evx-                    returnA -< x <$ ed-            run pa [1..4] `shouldBe` [4]--    describe "gather" $-      do-        it "correctly handles the end" $-          do-            let-                pa = proc x ->-                  do-                    r1 <- P.filter $ arr (\x -> x `mod` 3 == 0) -< x-                    r2 <- stopped -< x::Event Int-                    r3 <- returnA -< r2-                    fin <- gather -< [r1, r2, r3]-                    val <- hold 0 -< r1-                    end <- onEnd -< fin-                    returnA -< val <$ end-            run pa [1, 2, 3, 4, 5] `shouldBe` ([3]::[Int])---switches =-  do-    describe "switch" $-      do-        it "switches once" $-          do-            let-                before = proc evx ->-                  do-                    ch <- P.filterEvent (\x -> x `mod` 2 == 0) -< evx-                    returnA -< (noEvent, ch)--                after t = proc evx -> returnA -< (t*) <$> evx--                l = [1,3,4,1,3,2]--                -- 最初に偶数が与えられるまでは、入力を無視(NoEvent)し、-                -- それ以降は最初に与えられた偶数 * 入力値を返す-                ret = run (switch before after) l--                -- dが付くと次回からの切り替えとなる-                retD = run (dSwitch before after) l--            ret `shouldBe` [16, 4, 12, 8]-            retD `shouldBe` [4, 12, 8]--    describe "rSwitch" $-      do-        it "switches any times" $-          do-            let-               theArrow sw = proc evtp ->-                 do-                   evx <- P.fork -< fst <$> evtp-                   evarr <- P.fork -< snd <$> evtp-                   sw (arr $ fmap (+2)) -< (evx, evarr)--               l = [(Just 5, Nothing),-                    (Just 1, Just (arr $ fmap (*2))),-                    (Just 3, Nothing),-                    (Just 6, Just (arr $ fmap (*3))),-                    (Just 7, Nothing)]-               ret = run (theArrow rSwitch) l-               retD = run (theArrow drSwitch) l--            ret `shouldBe` [7, 2, 6, 18, 21]-            retD `shouldBe` [7, 3, 6, 12, 21]-    describe "kSwitch" $-      do-        it "switches spontaneously" $-          do-            let-                oneshot x = pure () >>> blockingSource [x]-                theArrow sw = sw (oneshot False) (arr snd) $ \_ _ -> oneshot True-            run (theArrow kSwitch) [] `shouldBe` [True]-            run (theArrow dkSwitch) [] `shouldBe` [False, True]--source =-  do-    describe "source" $-      do-        it "provides interleaved source stream" $-          do-            let-                pa = proc cl ->-                  do-                    s1 <- P.source [1, 2, 3] -< cl-                    s2 <- P.source [4, 5, 6] -< cl-                    P.gather -< [s1, s2]-            P.run pa (repeat ()) `shouldBe` [1, 4, 2, 5, 3, 6]-    describe "blockingSource" $-      do-        it "provides blocking source stream" $-          do-            let-                pa = proc _ ->-                  do-                    s1 <- P.blockingSource [1, 2, 3] -< ()-                    s2 <- P.blockingSource [4, 5, 6] -< ()-                    P.gather -< [s1, s2]-            P.run pa (repeat ()) `shouldBe` [4, 5, 6, 1, 2, 3]--    describe "source and blockingSource" $-      do-        prop "[interleave blockingSource = source]" $ \l cond ->-            let-                _ = l::[Int]-                equiv = mkEquivTest cond-                    ::(MyTestT (Event Int) (Event Int))-              in-                P.source l `equiv` P.interleave (P.blockingSource l)--        prop "[blocking source = blockingSource]" $ \l cond ->-            let-                _ = l::[Int]-                equiv = mkEquivTest cond-                    ::(MyTestT (Event Int) (Event Int))-              in-                (pure () >>> P.blockingSource l)-                    `equiv` (pure () >>> P.blocking (P.source l))---execution = describe "Execution of ProcessA" $-    do-      let-          pl =-            do-              x <- await-              yield x-              yield (x+1)-              x <- await-              yield x-              yield (x+1)-              yield (x+5)-          init = construct pl--      it "supports step execution" $-        do-          let-              (ret, now) = stepRun init 1-          yields ret `shouldBe` [1, 2]-          hasStopped ret `shouldBe` False--          let-              (ret, now2) = stepRun now 1-          yields ret `shouldBe` [1, 2, 6]-          hasStopped ret `shouldBe` True--          let-              (ret, _) = stepRun now2 1-          yields ret `shouldBe` ([]::[Int])-          hasStopped ret `shouldBe` True--      it "supports step execution (2)" $-          pendingWith "Correct stop handling"-{--      prop "supports step execution (2)" $ \p l ->-          let-              pa = mkProc p-              all pc (x:xs) ys =-                do-                  (r, cont) <- runKleisli (stepRun pc) x-                  all cont (if hasStopped r then [] else xs) (ys ++ yields r)-              all pc [] ys = runKleisli (run pc) [] >>= return . (ys++)-            in-              runState (all pa (l::[Int]) []) [] == stateProc pa l--}--      it "supports yield-driven step" $-        do-          let-              init = construct $-                do-                  yield (-1)-                  x <- await-                  mapM yield (iterate (+1) x) -- infinite--              (ret, now) = stepYield init 5-          yields ret `shouldBe` Just (-1)-          hasConsumed ret `shouldBe` False-          hasStopped ret `shouldBe` False--          let-              (ret, now2) = stepYield now 10-          yields ret `shouldBe` Just 10-          hasConsumed ret `shouldBe` True-          hasStopped ret `shouldBe` False--          let-              (ret, now3) = stepYield now2 10-          yields ret `shouldBe` Just 11-          hasConsumed ret `shouldBe` False-          hasStopped ret `shouldBe` False-