packages feed

machinecell 1.3.1 → 2.0.0

raw patch · 17 files changed

+1835/−1481 lines, 17 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Arrow.Machine: data ProcessA a b c
- Control.Arrow.Machine: fit :: (Arrow a, Arrow a') => (forall p q. a p q -> a' p q) -> ProcessA a b c -> ProcessA a' b c
- Control.Arrow.Machine.Core: data ProcessA a b c
- Control.Arrow.Machine.Core: fit :: (Arrow a, Arrow a') => (forall p q. a p q -> a' p q) -> ProcessA a b c -> ProcessA a' b c
- Control.Arrow.Machine.Event: class Occasional a where isOccasion x = not (isNoEvent x) && not (isEnd x)
- Control.Arrow.Machine.Event: data Event a
- Control.Arrow.Machine.Event: end :: Occasional a => a
- Control.Arrow.Machine.Event: evMap :: Arrow a => (b -> c) -> a (Event b) (Event c)
- Control.Arrow.Machine.Event: evMaybe :: Arrow a => c -> (b -> c) -> a (Event b) c
- Control.Arrow.Machine.Event: fromEvent :: Arrow a => b -> a (Event b) b
- Control.Arrow.Machine.Event: hEv :: ArrowApply a => a (e, b) c -> a e c -> a (e, Event b) c
- Control.Arrow.Machine.Event: hEv' :: ArrowApply a => a (e, b) c -> a e c -> a e c -> a (e, Event b) c
- Control.Arrow.Machine.Event: isEnd :: Occasional a => a -> Bool
- Control.Arrow.Machine.Event: isNoEvent :: Occasional a => a -> Bool
- Control.Arrow.Machine.Event: isOccasion :: Occasional a => a -> Bool
- Control.Arrow.Machine.Event: join :: (Arrow a, Occasional b) => a b (Event b)
- Control.Arrow.Machine.Event: join2 :: (Event a, Event b) -> Event (Event a, Event b)
- Control.Arrow.Machine.Event: noEvent :: Occasional a => a
- Control.Arrow.Machine.Event: split :: (Arrow a, Occasional b) => a (Event b) b
- Control.Arrow.Machine.Event: split2 :: Event (Event a, Event b) -> (Event a, Event b)
- Control.Arrow.Machine.Exception: bracket :: Monad m => PlanT i o m a -> (a -> PlanT i o m b) -> (a -> PlanT i o m c) -> PlanT i o m c
- Control.Arrow.Machine.Exception: bracketOnError :: Monad m => PlanT i o m a -> (a -> PlanT i o m b) -> (a -> PlanT i o m c) -> PlanT i o m c
- Control.Arrow.Machine.Exception: bracket_ :: Monad m => PlanT i o m a -> PlanT i o m b -> PlanT i o m c -> PlanT i o m c
- Control.Arrow.Machine.Exception: catch :: Monad m => PlanT i o m a -> PlanT i o m a -> PlanT i o m a
- Control.Arrow.Machine.Exception: finally :: Monad m => PlanT i o m a -> PlanT i o m b -> PlanT i o m a
- Control.Arrow.Machine.Exception: handle :: Monad m => PlanT i o m a -> PlanT i o m a -> PlanT i o m a
- Control.Arrow.Machine.Exception: onException :: Monad m => PlanT i o m a -> PlanT i o m b -> PlanT i o m a
- Control.Arrow.Machine.Plan: await :: Plan i o i
- Control.Arrow.Machine.Plan: construct :: ArrowApply a => Plan i o t -> ProcessA a (Event i) (Event o)
- Control.Arrow.Machine.Plan: 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.Plan: repeatedly :: ArrowApply a => Plan i o t -> ProcessA a (Event i) (Event o)
- Control.Arrow.Machine.Plan: 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.Plan: stop :: Plan i o a
- Control.Arrow.Machine.Plan: stopped :: (ArrowApply a, Occasional c) => ProcessA a b c
- Control.Arrow.Machine.Plan: type Plan i o a = forall m. Monad m => PlanT i o m a
- Control.Arrow.Machine.Plan: yield :: o -> Plan i o ()
- Control.Arrow.Machine.Running: ExecInfo :: fa -> Bool -> Bool -> ExecInfo fa
- Control.Arrow.Machine.Running: data ExecInfo fa
- Control.Arrow.Machine.Running: hasConsumed :: ExecInfo fa -> Bool
- Control.Arrow.Machine.Running: hasStopped :: ExecInfo fa -> Bool
- Control.Arrow.Machine.Running: instance Alternative f => Monoid (ExecInfo (f a))
- Control.Arrow.Machine.Running: instance Eq fa => Eq (ExecInfo fa)
- Control.Arrow.Machine.Running: instance Monoid r => Monoid (WithEnd r)
- Control.Arrow.Machine.Running: instance Show fa => Show (ExecInfo fa)
- Control.Arrow.Machine.Running: run :: ArrowApply a => ProcessA a (Event b) (Event c) -> a [b] [c]
- Control.Arrow.Machine.Running: runOn :: (ArrowApply a, Monoid r) => (c -> r) -> ProcessA a (Event b) (Event c) -> a [b] r
- Control.Arrow.Machine.Running: run_ :: ArrowApply a => ProcessA a (Event b) (Event c) -> a [b] ()
- Control.Arrow.Machine.Running: stepRun :: ArrowApply a => ProcessA a (Event b) (Event c) -> a b (ExecInfo [c], ProcessA a (Event b) (Event c))
- Control.Arrow.Machine.Running: stepYield :: ArrowApply a => ProcessA a (Event b) (Event c) -> a b (ExecInfo (Maybe c), ProcessA a (Event b) (Event c))
- Control.Arrow.Machine.Running: yields :: ExecInfo fa -> fa
- Control.Arrow.Machine.Types: Feed :: Phase
- Control.Arrow.Machine.Types: ProcessA :: StepType a b c -> ProcessA a b c
- Control.Arrow.Machine.Types: Suspend :: Phase
- Control.Arrow.Machine.Types: Sweep :: Phase
- Control.Arrow.Machine.Types: arrStep :: ArrowApply a => (b -> c) -> StepType a b c
- Control.Arrow.Machine.Types: compositeStep :: ArrowApply a => StepType a b d -> StepType a d c -> StepType a b c
- Control.Arrow.Machine.Types: compositeStep' :: ArrowApply a => Phase -> StepType a b d -> StepType a d c -> StepType a b c
- Control.Arrow.Machine.Types: data Phase
- Control.Arrow.Machine.Types: dimapStep :: Arrow a => (b -> c) -> (d -> e) -> StepType a c d -> StepType a b e
- Control.Arrow.Machine.Types: parStep :: (Arrow a, Arrow t, Monoid t4) => t (t2, t1) (t4, t5, a b c) -> t (t2, t3) (t4, t6, a b' c') -> t (t2, (t1, t3)) (t4, (t5, t6), a (b, b') (c, c'))
- Control.Arrow.Machine.Types: step :: ProcessA a b c -> StepType a b c
- Control.Arrow.Machine.Types: type StepType a b c = a (Phase, b) (Phase, c, ProcessA a b c)
- Control.Arrow.Machine.Utils: delay :: (ArrowApply a, Occasional b) => ProcessA a b b
- Control.Arrow.Machine.Utils: feedback :: (ArrowApply a, Occasional d) => ProcessA a (e, AS d) b -> ProcessA a (e, AS b) (c, d) -> ProcessA a (AS e) c
- Control.Arrow.Machine.Utils: feedback1 :: (ArrowApply a, Occasional d) => ProcessA a (e, AS d) (c, d) -> ProcessA a (AS e) c
+ Control.Arrow.Machine.Misc.Discrete: accum :: ArrowApply a => b -> ProcessA a (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: arr2 :: ArrowApply a => (b1 -> b2 -> c) -> ProcessA a (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: 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: 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: asUpdater :: ArrowApply a => a b c -> ProcessA a (T b) (Event c)
+ Control.Arrow.Machine.Misc.Discrete: constant :: ArrowApply a => c -> ProcessA a b (T c)
+ Control.Arrow.Machine.Misc.Discrete: data Alg a i o
+ Control.Arrow.Machine.Misc.Discrete: data T a
+ Control.Arrow.Machine.Misc.Discrete: edge :: ArrowApply a => ProcessA a (T b) (Event b)
+ Control.Arrow.Machine.Misc.Discrete: fromEq :: (ArrowApply a, Eq b) => ProcessA a b (T b)
+ Control.Arrow.Machine.Misc.Discrete: hold :: ArrowApply a => b -> ProcessA a (Event b) (T b)
+ Control.Arrow.Machine.Misc.Discrete: instance ArrowApply a => Applicative (Alg a i)
+ Control.Arrow.Machine.Misc.Discrete: instance ArrowApply a => Functor (Alg a i)
+ Control.Arrow.Machine.Misc.Discrete: updates :: T a -> (Event ())
+ Control.Arrow.Machine.Misc.Discrete: value :: T a -> a
+ Control.Arrow.Machine.Misc.Exception: bracket :: Monad m => PlanT i o m a -> (a -> PlanT i o m b) -> (a -> PlanT i o m c) -> PlanT i o m c
+ Control.Arrow.Machine.Misc.Exception: bracketOnError :: Monad m => PlanT i o m a -> (a -> PlanT i o m b) -> (a -> PlanT i o m c) -> PlanT i o m c
+ Control.Arrow.Machine.Misc.Exception: bracket_ :: Monad m => PlanT i o m a -> PlanT i o m b -> PlanT i o m c -> PlanT i o m c
+ Control.Arrow.Machine.Misc.Exception: catch :: Monad m => PlanT i o m a -> PlanT i o m a -> PlanT i o m a
+ Control.Arrow.Machine.Misc.Exception: finally :: Monad m => PlanT i o m a -> PlanT i o m b -> PlanT i o m a
+ Control.Arrow.Machine.Misc.Exception: handle :: Monad m => PlanT i o m a -> PlanT i o m a -> PlanT i o m a
+ Control.Arrow.Machine.Misc.Exception: onException :: Monad m => PlanT i o m a -> PlanT i o m b -> PlanT i o m a
+ Control.Arrow.Machine.Types: ExecInfo :: fa -> Bool -> Bool -> ExecInfo fa
+ Control.Arrow.Machine.Types: await :: Plan i o i
+ Control.Arrow.Machine.Types: catchP :: Monad m => PlanT i o m a -> PlanT i o m a -> PlanT i o m a
+ Control.Arrow.Machine.Types: class Occasional' a => Occasional a
+ Control.Arrow.Machine.Types: class Occasional' a
+ Control.Arrow.Machine.Types: collapse :: Occasional' a => a -> Event ()
+ Control.Arrow.Machine.Types: condEvent :: Bool -> Event a -> Event a
+ Control.Arrow.Machine.Types: construct :: ArrowApply a => Plan i o t -> ProcessA a (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: dSwitch :: ArrowApply a => ProcessA a b (c, Event t) -> (t -> ProcessA a b c) -> ProcessA a b c
+ Control.Arrow.Machine.Types: data Event a
+ Control.Arrow.Machine.Types: data ExecInfo fa
+ 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: drSwitch :: ArrowApply a => ProcessA a b c -> ProcessA a (b, Event (ProcessA a b c)) c
+ Control.Arrow.Machine.Types: end :: Occasional a => a
+ Control.Arrow.Machine.Types: evMap :: Arrow a => (b -> c) -> a (Event b) (Event c)
+ Control.Arrow.Machine.Types: filterEvent :: (a -> Bool) -> Event a -> Event a
+ Control.Arrow.Machine.Types: fitEx :: (Arrow a, Arrow a') => (forall p q. a (p, b) (q, c) -> a' (p, b') (q, c')) -> ProcessA a b c -> ProcessA a' b' c'
+ Control.Arrow.Machine.Types: hasConsumed :: ExecInfo fa -> Bool
+ Control.Arrow.Machine.Types: hasStopped :: ExecInfo fa -> Bool
+ Control.Arrow.Machine.Types: instance (Occasional a, Occasional b) => Occasional (a, b)
+ Control.Arrow.Machine.Types: instance (Occasional' a, Occasional' b) => Occasional' (a, b)
+ Control.Arrow.Machine.Types: instance Alternative f => Monoid (ExecInfo (f a))
+ Control.Arrow.Machine.Types: instance Arrow a => Functor (ProcessA a i)
+ Control.Arrow.Machine.Types: instance ArrowApply a => Applicative (ProcessA a i)
+ Control.Arrow.Machine.Types: instance Eq a => Eq (Event a)
+ Control.Arrow.Machine.Types: instance Eq fa => Eq (ExecInfo fa)
+ Control.Arrow.Machine.Types: instance Functor (PlanF i o)
+ Control.Arrow.Machine.Types: instance Functor Event
+ Control.Arrow.Machine.Types: instance Monoid (Builder a)
+ Control.Arrow.Machine.Types: instance Monoid r => Monoid (WithEnd r)
+ Control.Arrow.Machine.Types: instance Occasional (Event a)
+ Control.Arrow.Machine.Types: instance Occasional' (Event a)
+ Control.Arrow.Machine.Types: instance Semigroup a => Monoid (Event a)
+ Control.Arrow.Machine.Types: instance Show a => Show (Event a)
+ Control.Arrow.Machine.Types: instance Show fa => Show (ExecInfo fa)
+ 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: loop' :: ArrowApply a => d -> ProcessA a (b, d) (c, d) -> ProcessA a b c
+ Control.Arrow.Machine.Types: muted :: (ArrowApply a, Occasional' b, Occasional c) => ProcessA a b c
+ Control.Arrow.Machine.Types: noEvent :: Occasional a => a
+ 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: 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: 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: parB :: (ArrowApply a, Traversable col) => col (ProcessA a b c) -> ProcessA a 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: repeatedly :: ArrowApply a => Plan i o t -> ProcessA a (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: 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: 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: run :: ArrowApply a => ProcessA a (Event b) (Event c) -> a [b] [c]
+ Control.Arrow.Machine.Types: runOn :: (ArrowApply a, Monoid r) => (c -> r) -> ProcessA a (Event b) (Event c) -> a [b] r
+ Control.Arrow.Machine.Types: run_ :: ArrowApply a => ProcessA a (Event b) (Event c) -> a [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: stepYield :: ArrowApply a => ProcessA a (Event b) (Event c) -> a b (ExecInfo (Maybe c), ProcessA a (Event b) (Event c))
+ Control.Arrow.Machine.Types: stop :: Plan i o a
+ Control.Arrow.Machine.Types: stopped :: (ArrowApply a, Occasional c) => ProcessA a b c
+ 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: type Plan i o a = forall m. Monad m => PlanT i o m a
+ Control.Arrow.Machine.Types: unsafeExhaust :: (ArrowApply a, Foldable f) => a b (f c) -> ProcessA a b (Event c)
+ Control.Arrow.Machine.Types: unsafeSteady :: ArrowApply a => a b c -> ProcessA a b c
+ Control.Arrow.Machine.Types: yield :: o -> Plan i o ()
+ Control.Arrow.Machine.Types: yields :: ExecInfo fa -> fa
+ Control.Arrow.Machine.Utils: now :: ArrowApply a => ProcessA a b (Event ())
- Control.Arrow.Machine.Utils: encloseState :: (ArrowApply a, ArrowAddState s a a') => ProcessA a b c -> s -> ProcessA a' b c
+ Control.Arrow.Machine.Utils: encloseState :: (ArrowApply a, ArrowApply a', ArrowAddState s a a') => ProcessA a b c -> s -> ProcessA a' b c
- Control.Arrow.Machine.Utils: filter :: ArrowApply a => a o Bool -> ProcessA a (Event o) (Event o)
+ Control.Arrow.Machine.Utils: filter :: ArrowApply a => a b Bool -> ProcessA a (Event b) (Event b)
- Control.Arrow.Machine.Utils: onEnd :: (ArrowApply a, Occasional b) => ProcessA a b (Event ())
+ Control.Arrow.Machine.Utils: onEnd :: (ArrowApply a, Occasional' b) => ProcessA a b (Event ())

Files

CHANGELOG.md view
@@ -1,3 +1,15 @@+2.0.0+------------+* Relocate files+    * `catch` and its families are moved to Misc.Exception+* Performance improve+* Added primitives: `fitEx`, `unsafeSteady`, `unsafeExhaust`+* Added: `condEvent`, `filterEvent`, `muted`+* Added to Misc: `Discrete`, `Pump.asUpdater`, `Pump.Alg`+* Deleted deprecated: `hEv`, `hEv'`, `evMaybe`, `fromEvent`, `split`,+  `join`, `split2`, `join2`, `feedback`, `feedback1`, `isNoEvent`, `isOccasional`, `isEnd`+* Deleted `Foldable` and `Traversable` instance of `Event`.+* Added `Occasional'` by splitting some members from `Occasional`  1.3.1 ------------
machinecell.cabal view
@@ -1,5 +1,5 @@ name:                machinecell-version:             1.3.1+version:             2.0.0 synopsis:            Arrow based stream transducers license:             BSD3 license-file:        LICENSE@@ -21,10 +21,17 @@ 	AFRP-like utilities are also available.  library-  exposed-modules:     Control.Arrow.Machine, Control.Arrow.Machine.Event, Control.Arrow.Machine.Plan, Control.Arrow.Machine.Types, Control.Arrow.Machine.Utils, Control.Arrow.Machine.Running, Control.Arrow.Machine.ArrowUtil, Control.Arrow.Machine.Exception, Control.Arrow.Machine.Core, Control.Arrow.Machine.Misc.Pump-  other-modules:         Control.Arrow.Machine.Event.Internal, Control.Arrow.Machine.Plan.Internal+  exposed-modules:+        Control.Arrow.Machine,+        Control.Arrow.Machine.Types,+        Control.Arrow.Machine.Utils,+        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-  build-depends:       base >=4.0 && <5.0, mtl >=2.0.1.1, free >=4.5, profunctors >=4.0, arrows >=0.4.1.2, semigroups >=0.8.3.1+  ghc-options: -Wall+  build-depends:       base >=4.0 && <5.0, mtl >=2.0.1.1, free >=4.5 && < 4.12, profunctors >=4.0, arrows >=0.4.1.2, semigroups >=0.8.3.1   hs-source-dirs:      src   default-language:    Haskell2010 @@ -34,7 +41,7 @@   hs-source-dirs:      test   main-is:             spec.hs   other-modules:       RandomProc, LoopUtil-  Build-depends:       base >=4.0 && <5.0, mtl >=2.0.1.1, profunctors >=4.0, QuickCheck >=1.0, hspec >=0.2.0, machinecell -any+  Build-depends:       base >=4.0 && <5.0, mtl >=2.0.1.1, profunctors >=4.0, QuickCheck >=1.0, hspec >=0.2.0, arrows >=0.4.1.2, semigroups >=0.8.3.1, machinecell -any  source-repository head   type:		git@@ -44,4 +51,4 @@ source-repository this   type:		git   location:	https://github.com/as-capabl/machinecell.git-  tag:		release-1.3.1+  tag:		release-2.0.0
src/Control/Arrow/Machine.hs view
@@ -4,29 +4,306 @@ {-# LANGUAGE TypeSynonymInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE GADTs #-}
+
+{-|
+Module: Control.Arrow.Machine
+Description: Contains the main documentation and module imports.
+-}
 module
     Control.Arrow.Machine
       (
+        -- * Quick introduction
+        -- $introduction
+        
+        -- * Note
+        -- $note
+
         -- * Modules
-        module Control.Arrow.Machine.Event, 
-        module Control.Arrow.Machine.Utils,
-        module Control.Arrow.Machine.Plan,
-        module Control.Arrow.Machine.Exception,
-        module Control.Arrow.Machine.Running,
+        -- | "Control.Arrow.Machine" is good to import qualified, because no operators are exported.
+        --
+        -- Alternatively, you can import libraries below individually,
+        -- with only "Control.Arrow.Machine.Utils" qualified or identifier specified.
+        --
+        -- Control.Arrow.Machine.Misc.* are not included by default.
+        -- They are all designed to import qualified.
         module Control.Arrow.Machine.ArrowUtil,
-
-        -- * The transducer arrow
-        ProcessA(), 
-        fit
+        module Control.Arrow.Machine.Types,
+        module Control.Arrow.Machine.Utils
        )
 where
 
-import Control.Arrow.Machine.Event
-import Control.Arrow.Machine.Utils
-import Control.Arrow.Machine.Plan
-import Control.Arrow.Machine.Exception
-import Control.Arrow.Machine.Running
 import Control.Arrow.Machine.ArrowUtil
+import Control.Arrow.Machine.Types
+import Control.Arrow.Machine.Utils
 
+-- $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]
+--
+-- In above statement, "`evMap` (+1)" has a type "ProcessA (-\>) (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 (-\>)."
+--
+-- `ProcessA` 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`.
+--
+-- ProcessA can run the effects as following.
+--
+-- \>\>\> runKleisli (run_ $ anytime (Kleisli 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.
+--
+-- That is useful in the case rather side effects are main concern.
+--
+-- = ProcessA as pipes
+--
+-- "ProcessA a (Event b) (Event c)" transducers are actually one-directional composable pipes.
+--
+-- They can be constructed from `Plan` monads.
+-- 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.
+--
+-- Then, resulting processes are composed as `Category` using `(\>\>\>)` operator.
+--
+-- @
+-- 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
+-- @
+--
+-- \>\>\> runKleisli (run_ $ source \>\>\> pipe \>\>\> sink) (repeat ())
+--
+-- The above code reads two lines from stdin, puts a concatenated line to stdout and finishes.
+--
+-- Unlike other pipe libraries, even a source must call `await`.
+--
+-- The source awaits dummy input, namely "(repeat ())", and discard input values.
+-- Even the input is an infinite list, this program stops when the "pipe" transducer stops.
+--
+-- == More details on finalizing
+--
+-- Finalizing behavior of transducers obey the following scenario.
+-- 
+-- 1. Signals of type `Event` can carry /end signs/.
+-- 2. Most transducers stop when they get an end sign.
+--    (Some exceptions can be made by `onEnd` or `catchP`)
+-- 3. If `run` function detects an end sign as an output of a running transducer,
+--    it stops feeding input values and alternatively feeds end signs.
+-- 4. Continue iteration until no more events can be occurred.
+-- 
+-- So "await \`catchP\` some_cleanup" can handle any stop of both upstream and downstream.
+--
+-- On the other hand, a plan never gets end sign without calling await.
+-- That's why even sources must call await.
+--
+-- = Arrow composition
+--
+-- One of the most attractive feature of machinecell is the /arrow composition/.
+--
+-- In addition to `Category`, ProcessA 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]
+-- Odd: 1
+-- Even: 2
+-- Odd: 3
+-- Even: 4
+-- ...
+--
+-- The result implies that two statements that inputs x and their downstreams are
+-- executed in parallel.
+--
+-- = Behaviours
+--
+-- The transducers we have already seen are all have input and output type wrapped by `Event`.
+-- We have not taken care of them so far because all of them are cancelled each other.
+--
+-- But several built-in transducers provides 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` keeps the last input until a new value is provided.
+--
+-- `accum` updates its outputting by applying every input function.
+--
+-- According to a knowledge from arrowized FRP(functional reactive programming),
+-- values that appear naked in arrow notations are /behaviour/,
+-- that means /coutinuous/ time-varying values,
+-- whereas /event/ values are /discrete/.
+-- 
+-- Note that all values that can be input, output, or taken effects must be discrete.
+--
+-- To use continuous values anyhow interacting the real world,
+-- they must be encoded to discrete values.
+--
+-- That's done by functor calculations between any existing events.
+--
+-- 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]
+--
+-- `(\<$)` operator discards the value of rhs and only uses that's container structure
+-- e.g. 1 \<$ Just "a" =\> Just 1, 1 \<$ Nothing =\> Nothing,
+-- 1 \<$ [True, False, undefined] =\> [1, 1, 1].
+--
+-- In this case, the value of y are outputed according to the timing of x.
+--
 
-import Control.Arrow.Machine.Types
+
+
+-- $note
+-- = Purity of `ProcessA (-\>)`
+-- Since `a` of `ProcessA a b c` represents base monad(ArrowApply), `ProcessA (-\>)` is expected to be pure.
+--
+-- In other words, the following arrow results the same result for arbitrary `f`.
+--
+-- @
+-- proc x -\>
+--   do
+--     _ \<- fit arr f -\< x
+--     g -\< x
+-- @
+-- 
+-- Which is desugared to `f &&& g \>\>\> arr snd`. At least if `Event` constructor is exported,
+-- the proposition is falsible.
+-- When `f` is "arr (replicate k) \>\>\> fork" for some integer k and `g` is "arr (const $ Event ())",
+-- g yields ()s for k times. That is because, the result value of arrow "f &&& g" is
+-- nothing but "(Event x, Event ())" and its number of yields is k because "Event x" must
+-- be yielded k times. 
+--
+-- That's because `Event` constructor is hidden.
+-- Using primitives exported by this module, it works almost correctly.
+-- Event number is conserved by inserting an appropriate number of `NoEvent`s.
+-- But there is still a loophole.
+--
+-- Under the current implementation, the arrow below behaves like "arr (const $ Event x)".
+--
+-- @
+-- proc x -\> hold noEvent -\< ev \<$ ev
+-- @
+--
+-- I have an idea to correct this, such that the above arrow always be `NoEvent`.
+-- But in the result `Event` is no longer a functor in the meaning of haskell type class.
+--
+-- For now, if you never make value of nested event type like "ev \<$ ev",
+-- the problem will be avoided.
+--
+-- = Looping
+-- 
+-- Although `ProcessA` is an instance of `ArrowLoop`,
+-- to send values to upstream, there is a little difficulties.
+-- 
+-- In example below, result is [0, 1, 1, 1], not [0, 1, 2, 3].
+--
+-- @
+-- f = proc x -\>
+--   do
+--     rec
+--         b \<- dHold 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, 1, 1, 1]
+--
+-- This is because of machinecell's execution strategy.
+-- It's much similar to Prolog's backtracking stategy.
+-- At the time backtracking reaches `fork` three values are
+-- found and backtracking go and back three times between fork and returnA,
+-- but not reaches to dHold until all outputs are done.
+--
+-- In general, `Event` values should not be refered at upstream.
+--
+-- Rather, they should be encoded to behaviours and send to upstream in
+-- rec statement and delayed by `cycleDelay`.
+--
+-- Another way to send values to upstream is `encloseState`.
+--
+-- = Unsafe primitives
+--
+-- In the code below, `edge` does not fire.
+--
+-- @
+-- encloseState False (sta \>\>\> peekState) \>\>\> edge
+-- @
+--
+-- where
+--
+-- @
+-- sta = constructT (ary0 $ statefully unArrowMonad) (put True \>\> await \>\> put False)
+-- @
+--
+-- That is because, when "put True" is executing, the backtracking is going up and never hits `edge`
+-- until "put False" is executed.
+--
+-- The same occurs for "proc b -> if b then (now -< ()) else (returnA -< noEvent)" instead of `edge`.
+--
+-- Even worse, it again breaks the purity of `ProcessA`.
+-- `await` gets `NoEvent` if some "arr (replicate k) \>\>\> fork" is inserted somewhere in upstream.
+-- Then `edge` may fire because "put False" execution is delayed.
+--
+-- This means that, `encloseState`, `peekState`, `edge`, and `ArrowChoice` instance for `ProcessA`
+-- should never be existed simultaneously.
+--
+-- Moreover, their primitives `unsafeSteady`, `unsafeExhaust`, `fitEx` are so.
+--
+-- But I hope some of them can be rescued. So for now, this library contains them all.
+       
− src/Control/Arrow/Machine/Core.hs
@@ -1,40 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE Arrows #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE GADTs #-}---{-|-Extracted stuff to be used unqualified from ../Machine.hs.--}-module-    Control.Arrow.Machine.Core-      (-        -- * Modules-        module Control.Arrow.Machine.Event, ---        module Control.Arrow.Machine.Utils,-        module Control.Arrow.Machine.Plan,---        module Control.Arrow.Machine.Exception,-        module Control.Arrow.Machine.Running,---        module Control.Arrow.Machine.ArrowUtil,--        -- * The transducer arrow-        ProcessA(), -        fit,-       )-where--import Control.Arrow.Machine.Event--- import Control.Arrow.Machine.Utils-import Control.Arrow.Machine.Plan--- import Control.Arrow.Machine.Exception-import Control.Arrow.Machine.Running-import qualified Control.Arrow.Machine.Running as Running--- import Control.Arrow.Machine.ArrowUtil--import Control.Arrow.Machine.Types-import Control.Arrow--
− src/Control/Arrow/Machine/Event.hs
@@ -1,21 +0,0 @@-module-    Control.Arrow.Machine.Event -      (-        Occasional (..),-        Event (),--        -- * Deprecated-        -- |They should be used only for internal use.-        hEv, -        hEv', -        evMaybe,-        fromEvent,-        evMap,-        split,-        join,-        split2,-        join2-      )-where--import Control.Arrow.Machine.Event.Internal
− src/Control/Arrow/Machine/Event/Internal.hs
@@ -1,204 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE Arrows #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE GADTs #-}--module-    Control.Arrow.Machine.Event.Internal-where--import Control.Arrow-import Control.Applicative-import Data.Foldable-import Data.Traversable-import Data.Monoid (Monoid, mappend, mconcat, mempty)-import Data.Semigroup (Semigroup, (<>))-import Control.Monad (liftM, MonadPlus(..))-    -data Event a = Event a | NoEvent | End deriving (Eq, Show)---instance -    Functor Event -  where-    fmap f NoEvent = NoEvent-    fmap f End = End-    fmap f (Event x) = Event (f x)--{--instance -    Applicative Event -  where-    pure = Event--    (Event f) <*> (Event x) = Event $ f x-    End <*> _ = End-    _ <*> End = End-    _ <*> _ = NoEvent--}--instance-    Foldable Event-  where-    foldMap f (Event x) = f x-    foldMap _ NoEvent = mempty-    foldMap _ End = mempty---instance-    Traversable Event-  where-    traverse f (Event x) = Event <$> f x-    traverse f NoEvent = pure NoEvent-    traverse f End = pure End--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--{--instance-    Monad Event-  where-    return = Event--    Event x >>= f = f x-    NoEvent >>= _ = NoEvent-    End >>= _ = End--    _ >> End = End-    l >> r = l >>= const r-    -    fail _ = End---instance-    MonadPlus Event-  where-    mzero = End--    Event x `mplus` _ = Event x-    _ `mplus` Event x = Event x-    End `mplus` r = r-    l `mplus` End = l-    _ `mplus` _ = NoEvent--}-----class -    Occasional a-  where-    noEvent :: a-    end :: a-    isNoEvent :: a -> Bool-    isEnd :: a -> Bool-    isOccasion :: a -> Bool-    isOccasion x = not (isNoEvent x) && not (isEnd x)--instance-    (Occasional a, Occasional b) => Occasional (a, b)-  where-    noEvent = (noEvent, noEvent)-    end = (end, end)-    isOccasion xy@(x, y) = -        (isOccasion x || isOccasion y) && not (isEnd xy)-    isNoEvent xy = -        not (isOccasion xy) && not (isEnd xy)-    isEnd (x, y) = isEnd x && isEnd y-----instance -    Occasional (Event a)-  where-    noEvent = NoEvent-    end = End-    isNoEvent NoEvent = True-    isNoEvent _ = False-    isEnd End = True-    isEnd _ = False--hEv :: ArrowApply a => a (e,b) c -> a e c -> a (e, Event b) c-hEv f1 f2 = proc (e, ev) ->-    helper ev -<< e-  where-    helper (Event x) = proc e -> f1 -< (e, x)-    helper NoEvent = f2-    helper End = f2--hEv' :: ArrowApply a => a (e,b) c -> a e c -> a e c -> a (e, Event b) c-hEv' f1 f2 f3 = proc (e, ev) ->-    helper ev -<< e-  where-    helper (Event x) = proc e -> f1 -< (e, x)-    helper NoEvent = f2-    helper End = f3-----evMaybe :: Arrow a => c -> (b->c) -> a (Event b) c-evMaybe r f = arr (go r f)-  where-    go _ f (Event x) = f x-    go r _ NoEvent = r-    go r _ End = r---fromEvent :: Arrow a => b -> a (Event b) b-fromEvent x = evMaybe x id----- TODO: テスト-condEvent :: Bool -> Event a -> Event a-condEvent _ End = End-condEvent True ev = ev-condEvent False ev = NoEvent----- TODO: テスト-filterEvent :: (a -> Bool) -> Event a -> Event a-filterEvent cond ev@(Event x) = condEvent (cond x) ev-filterEvent _ ev = ev---evMap ::  Arrow a => (b->c) -> a (Event b) (Event c)-evMap = arr . fmap----- TODO: テスト-split :: (Arrow a, Occasional b) => a (Event b) b-split = arr go-  where-    go (Event x) = x-    go NoEvent = noEvent-    go End = end---join :: (Arrow a, Occasional b) => a b (Event b)-join = arr go-  where-    go x -       | isEnd x = End-       | isNoEvent x = NoEvent-       | otherwise = Event x---split2 :: Event (Event a, Event b) -> (Event a, Event b)-split2 = split---join2 :: (Event a, Event b) -> Event (Event a, Event b)-join2 = join
− src/Control/Arrow/Machine/Exception.hs
@@ -1,98 +0,0 @@---module-    Control.Arrow.Machine.Exception-      (-        catch,-        handle,-        bracket,-        bracket_,-        bracketOnError,-        finally,-        onException-       )-where--import qualified Control.Monad.Trans.Free as F-import qualified Control.Monad.Trans.Free.Church as F--import Data.Functor ((<$>))--import Control.Arrow.Machine.Types-import Control.Arrow.Machine.Event-import Control.Arrow.Machine.Event.Internal (Event(..))--import Control.Arrow.Machine.Plan.Internal-import Control.Arrow.Machine.Plan--import Debug.Trace---catch :: Monad m =>-    PlanT i o m a -> PlanT i o m a -> PlanT i o m a--catch pl cont = -    F.toFT $ catch' (F.fromFT pl) (F.fromFT cont)--catch' (F.FreeT mf) cont@(F.FreeT mcont) = -    F.FreeT $ mf >>= go-  where-    go (F.Pure a) = return $ F.Pure a-    go (F.Free StopPF) = mcont-    go (F.Free (AwaitPF f ff)) = -        return $ F.Free $ -        AwaitPF (\i -> f i `catch'` cont) (ff `catch'` cont)-    go (F.Free fft) = -        return $ F.Free $ (`catch'` cont) <$> fft--handle :: Monad m =>-    PlanT i o m a -> PlanT i o m a -> PlanT i o m a--handle = flip catch---bracket :: Monad m =>-    PlanT i o m a -> (a -> PlanT i o m b)-> (a -> PlanT i o m c) -> PlanT i o m c-bracket before after thing =-  do-    a <- before-    r <- thing a `catch` (after a >> stop)-    _ <- after a-    return r---bracket_ :: Monad m =>-    PlanT i o m a -> PlanT i o m b-> PlanT i o m c -> PlanT i o m c-bracket_ before after thing =-  do-    before-    r <- thing `catch` (after >> stop)-    _ <- after-    return r---bracketOnError :: Monad m =>-    PlanT i o m a -> (a -> PlanT i o m b)-> (a -> PlanT i o m c) -> PlanT i o m c-bracketOnError before after thing =-  do-    a <- before-    r <- thing a `catch` (after a >> stop)-    return r---finally :: Monad m =>-    PlanT i o m a -> PlanT i o m b-> PlanT i o m a-finally thing after =-  do-    r <- thing `catch` (after >> stop)-    _ <- after-    return r---onException :: Monad m =>-    PlanT i o m a -> PlanT i o m b-> PlanT i o m a-onException thing after =-  do-    thing `catch` (after >> stop)-    -
+ src/Control/Arrow/Machine/Misc/Discrete.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module+    Control.Arrow.Machine.Misc.Discrete+      (+        -- *Discrete+        -- | This module should be imported manually.+        T(),+        updates,+        value,+        +        arr,+        arr2,+        arr3,+        arr4,+        arr5,++        constant,+        hold,+        accum,+        fromEq,+        +        edge,+        asUpdater,+        Alg+      )+where++import Prelude hiding (id, (.))+import Control.Category+import Control.Arrow hiding (arr)+import Control.Applicative+import qualified Control.Arrow as Arr+import qualified Control.Arrow.Machine as P+import Data.Monoid (mconcat, mappend)++data T a = T {+    updates :: (P.Event ()),+    value :: a+  }++makeT ::+    ArrowApply a =>+    P.ProcessA a (P.Event (), b) (T b)+makeT = Arr.arr $ uncurry T++arr ::+    ArrowApply a =>+    (b->c) ->+    P.ProcessA a (T b) (T c)+arr f =+    Arr.arr $ \(T ev x) ->+        T ev (f x)++arr2 ::+    ArrowApply a =>+    (b1->b2->c) ->+    P.ProcessA a (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 =>+    (b1->b2->b3->c) ->+    P.ProcessA a (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 =>+    (b1->b2->b3->b4->c) ->+    P.ProcessA a (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 =>+    (b1->b2->b3->b4->b5->c) ->+    P.ProcessA a (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 =>+    c ->+    P.ProcessA a b (T c)+constant x =+    (P.now &&& Arr.arr (const x)) >>> makeT++onUpdate ::+    ArrowApply a =>+    P.ProcessA a (P.Event b) (P.Event ())+onUpdate = proc ev ->+  do+    n <- P.now -< ()+    returnA -< n `mappend` P.collapse ev++hold ::+    ArrowApply a =>+    b ->+    P.ProcessA a (P.Event b) (T b)+hold i =+    (onUpdate &&& P.hold i) >>> makeT++accum ::+    ArrowApply a =>+    b ->+    P.ProcessA a (P.Event (b->b)) (T b)+accum i =+    (onUpdate &&& P.accum i) >>> makeT++fromEq ::+    (ArrowApply a, Eq b) =>+    P.ProcessA a 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)+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++++newtype Alg a i o = Alg { eval :: P.ProcessA a i (T o) }++instance+    ArrowApply a => Functor (Alg a i)+  where+    fmap f alg = Alg $ eval alg >>> arr f++instance+    ArrowApply a => Applicative (Alg a i)+  where+    pure = Alg . constant+    af <*> aa = Alg $ (eval af &&& eval aa) >>> arr2 ($)
+ src/Control/Arrow/Machine/Misc/Exception.hs view
@@ -0,0 +1,76 @@+++module+    Control.Arrow.Machine.Misc.Exception+      (+        catch,+        handle,+        bracket,+        bracket_,+        bracketOnError,+        finally,+        onException+       )+where+++import Control.Arrow.Machine.Types+++catch :: Monad m =>+    PlanT i o m a -> PlanT i o m a -> PlanT i o m a++catch = catchP+++handle :: Monad m =>+    PlanT i o m a -> PlanT i o m a -> PlanT i o m a++handle = flip catch+++bracket :: Monad m =>+    PlanT i o m a -> (a -> PlanT i o m b)-> (a -> PlanT i o m c) -> PlanT i o m c+bracket before after thing =+  do+    a <- before+    r <- thing a `catch` (after a >> stop)+    _ <- after a+    return r+++bracket_ :: Monad m =>+    PlanT i o m a -> PlanT i o m b-> PlanT i o m c -> PlanT i o m c+bracket_ before after thing =+  do+    _ <- before+    r <- thing `catch` (after >> stop)+    _ <- after+    return r+++bracketOnError :: Monad m =>+    PlanT i o m a -> (a -> PlanT i o m b)-> (a -> PlanT i o m c) -> PlanT i o m c+bracketOnError before after thing =+  do+    a <- before+    r <- thing a `catch` (after a >> stop)+    return r+++finally :: Monad m =>+    PlanT i o m a -> PlanT i o m b-> PlanT i o m a+finally thing after =+  do+    r <- thing `catch` (after >> stop)+    _ <- after+    return r+++onException :: Monad m =>+    PlanT i o m a -> PlanT i o m b-> PlanT i o m a+onException thing after =+  do+    thing `catch` (after >> stop)+    +
src/Control/Arrow/Machine/Misc/Pump.hs view
@@ -30,7 +30,7 @@ import qualified Control.Arrow.Machine as P import Data.Monoid (Endo(Endo), mappend, appEndo) -newtype Duct a = Duct { unDuct :: Endo [a] }+newtype Duct a = Duct (Endo [a])  oneMore ::     ArrowApply a =>
− src/Control/Arrow/Machine/Plan.hs
@@ -1,144 +0,0 @@-{-# LANGUAGE Arrows #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}--{-|-A coroutine monad, inspired by machines library.--}-module-    Control.Arrow.Machine.Plan-      (-        -- * Types and Primitives-        PlanT,-        Plan,--        await,-        yield,-        stop,--        stopped,--        -- * Constructing machines-        constructT,-        repeatedlyT,--        construct,-        repeatedly-       )-where--import qualified Control.Category as Cat-import qualified Control.Monad.Trans.Free as F-import qualified Control.Monad.Trans.Free.Church as F--import Data.Monoid (mappend)-import Data.Functor ((<$>))-import Control.Monad-import Control.Arrow-import Control.Monad.Trans-import Debug.Trace--import Control.Arrow.Machine.ArrowUtil-import Control.Arrow.Machine.Types-import Control.Arrow.Machine.Event-import Control.Arrow.Machine.Event.Internal (Event(..))--import Control.Arrow.Machine.Plan.Internal--stopped :: -    (ArrowApply a, Occasional c) => ProcessA a b c-stopped = arr (const end)------yield :: o -> Plan i o ()-yield x = F.liftF $ YieldPF x ()--await :: Plan i o i-await = F.FT $ \pure free -> free (AwaitPF pure (free StopPF))--stop :: Plan i o a-stop = F.liftF $ StopPF-------constructT :: (Monad m, ArrowApply a) => -              (forall b. m b -> a () b) ->-              PlanT i o m r -> -              ProcessA a (Event i) (Event o)--constructT fit pl = ProcessA $ fit' $ F.runFT pl pure free-  where-    fit' ma = proc arg -> do { (evx, pa) <- fit ma -< (); modFit evx pa -<< arg }-    -    modFit :: ArrowApply a => Event c -> StepType a b (Event c) -> StepType a b (Event c)-    modFit (Event x) stp = retArrow Feed (Event x) (ProcessA stp)-    modFit End stp = retArrow Feed End (ProcessA stp)-    modFit _ stp = stp--    retArrow ph' evx cont = arr $ \(ph, _) -> -        case ph of-          Suspend -> -              (ph `mappend` Suspend,-               if isEnd evx then End else NoEvent,-               ProcessA $ retArrow ph' evx cont)-          _ -> -              (ph `mappend` ph', evx, cont)--    pure _ = return $ (End, retArrow Suspend End stopped)--    free (AwaitPF f ff) =-      do-        return $ (NoEvent, arr (uncurry (awaitIt f ff)) >>> proc pc -> pc -<< ())--    free (YieldPF y fc) = return $ (Event y, fit' fc)--    free StopPF = return $ (End, retArrow Suspend End stopped)---    awaitIt f _ Feed (Event x) = proc _ ->-      do-        (evy, stp) <- fit (f x) -< ()-        returnA -< (Feed, evy, ProcessA stp)--    awaitIt _ ff Feed End = proc _ ->-      do-        (evy, stp) <- fit ff -< ()-        returnA -< (Feed, evy, ProcessA stp)--    awaitIt _ ff Sweep End = proc _ ->-      do-        (evy, stp) <- fit ff -< ()-        returnA -< (if not $ isNoEvent evy then Feed else Suspend, evy, ProcessA stp)--    awaitIt f ff ph evx = proc _ ->-        returnA -< (ph `mappend` Suspend, NoEvent, -                    ProcessA $ arr (uncurry (awaitIt f ff)) >>> proc pc -> pc -<< ())---repeatedlyT :: (Monad m, ArrowApply a) => -              (forall b. m b -> a () b) ->-              PlanT i o m r -> -              ProcessA a (Event i) (Event o)--repeatedlyT f pl = constructT f $ forever pl----- for pure-construct :: ArrowApply a =>-             Plan i o t -> -             ProcessA a (Event i) (Event o)-construct pl = constructT (ary0 unArrowMonad) pl--repeatedly :: ArrowApply a =>-              Plan i o t -> -              ProcessA a (Event i) (Event o)-repeatedly pl = construct $ forever pl
− src/Control/Arrow/Machine/Plan/Internal.hs
@@ -1,23 +0,0 @@-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE GADTs #-}--module-    Control.Arrow.Machine.Plan.Internal-where--import qualified Control.Monad.Trans.Free as F-import qualified Control.Monad.Trans.Free.Church as F--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 g StopPF = StopPF---type PlanT i o m a = F.FT (PlanF i o) m a-type Plan i o a = forall m. Monad m => PlanT i o m a
− src/Control/Arrow/Machine/Running.hs
@@ -1,296 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE Arrows #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE MultiWayIf #-}--module-    Control.Arrow.Machine.Running-      (-        -- * Run at once.-        run,-        runOn,-        run_,-        -- * Run step-by-step.-        ExecInfo(..),-        stepRun,-        stepYield-      )-where--import Control.Arrow-import Control.Applicative (Alternative (..))-import Control.Monad.State-import Control.Monad.Writer-import Data.Monoid (Monoid (..), Endo(..), appEndo)-import Data.Maybe (fromMaybe)--import Control.Arrow.Machine.ArrowUtil-import Control.Arrow.Machine.Types-import Control.Arrow.Machine.Event-import Control.Arrow.Machine.Event.Internal (Event(..))-------- Utilities----while_ ::-    Monad m =>-    m Bool -> m a -> m ()-while_ cond body =-  do-    b <- cond-    if b-        then body >> while_ cond body-        else return ()---- | Monoid wrapper-data WithEnd r = WithEnd { -    getRWE :: r,-    getContWE :: Bool-  }--instance-    Monoid r => Monoid (WithEnd r)-  where-    mempty = WithEnd mempty True-    WithEnd x True `mappend` WithEnd y b = WithEnd (x `mappend` y) b-    mx@(WithEnd x False) `mappend` _ = mx-------- 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 => -    i -> i -> RM a i o 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--feed :: -    Monad m => -    i -> RM a (Event i) o m Bool-feed x = feed_ (Event x) NoEvent---finalizeE :: -    Monad m => -    RM a (Event i) o m Bool-finalizeE = feed_ End End---freeze ::-    Monad m =>-    RM a i o m (ProcessA a i o)-freeze = gets freezeRI-    --sweep :: -    Monad m =>-    RM a i o m o-sweep =-  do-    pa <- freeze-    fit <- gets getFitRI-    ph <- gets getPhaseRI-    x <- if ph == Feed-        then gets getInputRI-        else gets getPaddingRI-    -    (ph', y, pa') <- lift $ fit (step pa) (ph, x)-    -    ri <- get-    put $ ri {-        freezeRI = -            pa',-        getPhaseRI = -            if ph' == Feed then Sweep else ph'-      }--    return y---sweepAll :: -    (ArrowApply a, Monoid r, Monad m) =>-    (o->r) ->-    WriterT (WithEnd r) (RM a i (Event o) m) ()-sweepAll outpre = -        while_ -            ((not . (== Suspend)) `liftM` lift (gets getPhaseRI)) $-          do-            evx <- lift sweep-            case evx-              of-                Event x ->-                    tell (WithEnd (outpre x) True)-                NoEvent ->-                    return ()-                End ->-                    tell (WithEnd mempty False)----- | Run a machine with results concatenated in terms of a monoid.-runOn ::-    (ArrowApply a, Monoid r) =>-    (c -> r) ->-    ProcessA a (Event b) (Event c) ->-    a [b] r-runOn outpre pa0 = unArrowMonad $ \xs ->-  do-    wer <- runRM arrowMonad pa0 $ execWriterT $ -      do-        go xs-        lift (feed_ End End)-        sweepAll outpre-    return $ getRWE wer--  where-    go xs =-      do-        (_, wer) <- listen $ sweepAll outpre-        if getContWE wer then cont xs else return ()--    cont [] = return ()--    cont (x:xs) =-      do-        lift $ feed x-        go xs----- | Run a machine.-run :: -    ArrowApply a => -    ProcessA a (Event b) (Event c) -> -    a [b] [c]-run pa = -    runOn (\x -> Endo (x:)) pa >>>-    arr (appEndo `flip` [])---- | 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, -- [a] or Maybe a-        hasConsumed :: Bool,-        hasStopped :: Bool-      }-    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 suspended.-stepRun :: -    ArrowApply a =>-    ProcessA a (Event b) (Event c) ->-    a b (ExecInfo [c], ProcessA a (Event b) (Event c))--stepRun pa0 = unArrowMonad $ \x ->-  do-    (pa, wer)  <- runRM arrowMonad pa0 $ runWriterT $ -      do-        sweepAll singleton-        lift $ feed x-        sweepAll singleton-        lift $ freeze-    return $ (retval wer, pa)--  where-    singleton x = Endo (x:)--    retval WithEnd {..} = ExecInfo {-        yields = appEndo getRWE [], -        hasConsumed = True, -        hasStopped = not getContWE-      }---- | 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 $ feed x-        modify $ \ri -> ri { hasConsumed = csmd }-                             -        evo <- lift sweep-        -        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 }
src/Control/Arrow/Machine/Types.hs view
@@ -1,221 +1,1171 @@ {-# LANGUAGE Arrows #-} {-# LANGUAGE RankNTypes #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-}--module-    Control.Arrow.Machine.Types-    -- This file includes internals. Export definitions is at ../Machine.hs-where--import qualified Control.Category as Cat-import Data.Monoid (Monoid(..))-import Data.Profunctor (Profunctor, dimap)-import Control.Arrow.Operations (ArrowReader(..))-import Control.Arrow.Transformer.Reader (runReader, ArrowAddReader(..))-import Control.Arrow----- | 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 StepType a b c = a (Phase, b) (Phase, c, ProcessA a 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.------ May use `ArrowChoice` and `ArrowLoop` instance too.--- but there is a limitation that `loop` cannot propagate `Event`s to upstream.--- In such case, use `Control.Arrow.Machine.Utils.feedback` instead.-data ProcessA a b c = ProcessA { -      step :: StepType a b c-    }--fit :: (Arrow a, Arrow a') => -       (forall p q. a p q -> a' p q) -> -       ProcessA a b c -> ProcessA a' b c-fit f (ProcessA af) = ProcessA $ f af >>> arr mod-  where-    mod (ph, y, next) = (ph, y, fit f next)---instance-    Arrow a => Profunctor (ProcessA a)-  where-    dimap f g pa = ProcessA $ dimapStep f g (step pa)-    {-# INLINE dimap #-}--dimapStep :: Arrow a => -             (b->c)->(d->e)->-             StepType a c d -> StepType a b e-dimapStep f g stp = proc (ph, x) ->-  do-    (ph', y, pa') <- stp -< (ph, f x)-    returnA -< (ph', g y, dimap f g pa')-{-# INLINE [1] dimapStep #-}---instance-    ArrowApply a => Cat.Category (ProcessA a)-  where-    id = ProcessA (arrStep id)-    {-# INLINE id #-}-    g . f = ProcessA $ compositeStep (step f) (step g)-    {-# INLINE (.) #-}---instance -    ArrowApply a => Arrow (ProcessA a)-  where-    arr = ProcessA . arrStep-    {-# INLINE arr #-}--    first pa = ProcessA $ proc (ph, (x, d)) ->-      do-        (ph', y, pa') <- step pa -< (ph, x)-        returnA -< (ph' `mappend` Suspend, (y, d), first pa')-    {-# INLINE first #-}--    pa *** pb = ProcessA $ parStep (step pa) (step pb)-    {-# INLINE (***) #-}---parStep f g = proc (ph, (x1, x2)) ->-  do-    (ph1, y1, pa') <- f -< (ph, x1)-    (ph2, y2, pb') <- g -< (ph, x2)-    returnA -< (ph1 `mappend` ph2, (y1, y2), pa' *** pb')-{-# INLINE [1] parStep #-}--arrStep :: ArrowApply a => (b->c) -> StepType a b c-arrStep f = proc (ph, x) ->-    returnA -< (ph `mappend` Suspend, f x, ProcessA $ arrStep f)-{-# INLINE [1] arrStep #-}----- |Composition is proceeded by the backtracking strategy.-compositeStep :: ArrowApply a => -              StepType a b d -> StepType a d c -> StepType a b c-compositeStep f g = proc (ph, x) -> compositeStep' ph f g -<< (ph, x)-{-# INLINE [1] compositeStep #-}--compositeStep' :: ArrowApply a => -              Phase -> -              StepType a b d -> StepType a d c -> StepType a b c-             -compositeStep' Sweep f g = proc (_, x) ->-  do-    (ph1, r1, pa') <- f -< (Suspend, x)-    (ph2, r2, pb') <- g -<< (Sweep, r1)-    cont ph2 x -<< (r2, pa', pb')-  where-    cont Feed x = arr $ \(r, pa, pb) -> (Feed, r, pa >>> pb)-    cont Sweep x = arr $ \(r, pa, pb) -> (Sweep, r, pa >>> pb)-    cont Suspend x = proc (_, pa, pb) ->-      do-        (ph1, r1, pa') <- step pa -<< (Sweep, x)-        (ph2, r2, pb') <- step pb -<< (ph1, r1)-        returnA -< (ph2, r2, pa' >>> pb')--compositeStep' ph f g = proc (_, x) ->-  do-    (ph1, r1, pa') <- f -< (ph, x)-    (ph2, r2, pb') <- g -<< (ph1, r1)-    returnA -< (ph2, r2, pa' >>> pb')---- rules-{-# RULES-"ProcessA: concat/concat" -    forall f g h. compositeStep (compositeStep f g) h = compositeStep f (compositeStep g h)-"ProcessA: arr/arr"-    forall f g. compositeStep (arrStep f) (arrStep g) = arrStep (g . f)-"ProcessA: arr/*"-    forall f g. compositeStep (arrStep f) g = dimapStep f id g-"ProcessA: */arr"-    forall f g. compositeStep f (arrStep g) = dimapStep id g f-"ProcessA: dimap/dimap"-    forall f g h i j. dimapStep f j (dimapStep g i h)  = dimapStep (g . f) (j . i) h-"ProcessA: dimap/arr"-    forall f g h. dimapStep f h (arrStep g) = arrStep (h . g . f)-"ProcessA: par/par"-    forall f1 f2 g1 g2 h. compositeStep (parStep f1 f2) (compositeStep (parStep g1 g2) h) =-        compositeStep (parStep (compositeStep f1 g1) (compositeStep f2 g2)) h-"ProcessA: par/par-2"-    forall f1 f2 g1 g2. compositeStep (parStep f1 f2) (parStep g1 g2) =-        parStep (compositeStep f1 g1) (compositeStep f2 g2)-  #-}----instance-    ArrowApply a => ArrowChoice (ProcessA a)-  where-    left pa@(ProcessA a) = ProcessA $ proc (ph, eth) -> go ph eth -<< ()-      where-        go ph (Left x) = proc _ -> -          do-            (ph', y, pa') <- a -< (ph, x)-            returnA -< (ph', Left y, left pa')-        go ph (Right d) = proc _ -> -            returnA -< (ph `mappend` Suspend, Right d, left pa)--instance-    (ArrowApply a, ArrowLoop a) => ArrowLoop (ProcessA a)-  where-    loop pa = ProcessA $ proc (ph, x) -> loop $ go ph -<< x-      where-        go ph = proc (x, d) ->-          do -            (ph', (y, d'), pa') <- step pa -< (ph, (x, d))-            returnA -< ((ph', y, loop pa'), d')---instance-    (ArrowApply a, ArrowReader r a) => -    ArrowReader r (ProcessA a)-  where-    readState = ProcessA $ proc (ph, dm) ->-      do-        r <- readState -< dm-        returnA -< (ph `mappend` Suspend, r, readState)--    newReader pa = ProcessA $ proc (ph, (e, r)) ->-      do-        (ph', y, pa') <- newReader (step pa) -< ((ph, e), r)-        returnA -< (ph', y, newReader pa')--instance-    (ArrowApply a, ArrowApply a', ArrowAddReader r a a') =>-    ArrowAddReader r (ProcessA a) (ProcessA a')-  where-    liftReader pa = ProcessA $ proc (ph, x) ->-      do-        (ph', y, pa') <- (| liftReader (step pa -< (ph, x)) |)-        returnA -< (ph', y, liftReader pa)--    elimReader pra = -        ProcessA $ arr pre >>> elimReader (step pra) >>> arr post-      where-        pre (ph, (x, r)) = ((ph, x), r)-        post (ph, x, pra') = (ph, x, elimReader pra')+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE FlexibleContexts #-}++module+    Control.Arrow.Machine.Types+      (+        -- * Basic types+        ProcessA(),++        Occasional' (..),+        Occasional (..),+        Event (),+        condEvent,+        filterEvent,+        evMap,+        +        -- * Plan monads+        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,+        pSwitch,+        pSwitchB,+        rpSwitch,+        rpSwitchB,+        par,+        parB,++        +        -- * Primitive machines - other safe primitives+        fit,+        loop',+        +        -- * Primitive machines - unsafe+        fitEx,+        unsafeSteady,+        unsafeExhaust,+      )+where++import qualified Control.Category as Cat+import Data.Profunctor (Profunctor, dimap, rmap)+import Control.Arrow.Operations (ArrowReader(..))+import Control.Arrow.Transformer.Reader (ArrowAddReader(..))+import Control.Arrow+import Control.Monad hiding (join)+import Control.Monad.Trans+import Control.Monad.State hiding (join)+import Control.Monad.Writer hiding ((<>), join)+import Control.Applicative hiding (pure)+import qualified Control.Applicative as Ap+import Data.Foldable as Fd+import Data.Traversable as Tv+import Data.Semigroup (Semigroup, (<>))+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 StepType a b c = a (Phase, b) (Phase, c, ProcessA a 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.+newtype ProcessA a b c = ProcessA { +      step :: StepType a b c+    }+++fitEx :: (Arrow a, Arrow a') =>+    (forall p q. a (p, b) (q, c) -> a' (p, b') (q, c')) ->+    ProcessA a b c ->+    ProcessA a' b' c'+fitEx f k = ProcessA $ proc (ph, x) ->+  do+    ((ph', k'), y) <- f (step k >>> arr (\(ph', y, k') -> ((ph', k'), y))) -< (ph, x)+    returnA -< (ph', y, fitEx f k')+++fit :: (Arrow a, Arrow a') => +       (forall p q. a p q -> a' p q) -> +       ProcessA a b c -> ProcessA a' b c+fit f = fitEx f+++loop' :: ArrowApply a =>+    d ->+    ProcessA a (b, d) (c, d) ->+    ProcessA a b c+loop' i pa = ProcessA $ proc (ph, x) ->+  do+    (ph', (y, n), pa') <- step pa -< (ph, (x, i))+    returnA -< (ph', y, loop' n pa')++instance+    Arrow a => Profunctor (ProcessA a)+  where+    dimap f g pa = ProcessA $ dimapStep f g (step pa)+    {-# INLINE dimap #-}++dimapStep :: Arrow a => +             (b->c)->(d->e)->+             StepType a c d -> StepType a b e+dimapStep f g stp = proc (ph, x) ->+  do+    (ph', y, pa') <- stp -< (ph, f x)+    returnA -< (ph', g y, dimap f g pa')+{-# NOINLINE dimapStep #-}++instance+    Arrow 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 = ProcessA idStep+    {-# INLINE id #-}+    g . f = ProcessA $ compositeStep (step f) (step g)+    {-# INLINE (.) #-}+++instance +    ArrowApply a => Arrow (ProcessA a)+  where+    arr = ProcessA . arrStep+    {-# INLINE arr #-}++    first pa = ProcessA $ parStep (step pa) idStep+    {-# INLINE first #-}++    second pa = ProcessA $ parStep idStep (step pa)+    {-# INLINE second #-}++    pa *** pb = ProcessA $ parStep (step pa) (step pb)+    {-# INLINE (***) #-}+++parStep :: ArrowApply a =>+    StepType a b c ->+    StepType a d e ->+    StepType a (b, d) (c, e)+parStep f g = proc (ph, (x1, x2)) ->+  do+    (ph1, y1, pa') <- f -< (ph, x1)+    (ph2, y2, pb') <- g -< (ph, x2)+    returnA -< (ph1 `mappend` ph2, (y1, y2), pa' *** pb')+{-# NOINLINE parStep #-}++idStep :: ArrowApply a => StepType a b b+idStep = proc (ph, x) ->+    returnA -< (ph `mappend` Suspend, x, ProcessA $ idStep)+{-# NOINLINE idStep #-}++arrStep :: ArrowApply a => (b->c) -> StepType a b c+arrStep f = proc (ph, x) ->+    returnA -< (ph `mappend` Suspend, f x, ProcessA $ arrStep f)+{-# NOINLINE arrStep #-}+++-- |Composition is proceeded by the backtracking strategy.+compositeStep :: ArrowApply a => +              StepType a b d -> StepType a d c -> StepType a b c+compositeStep f g = proc (ph, x) -> compositeStep' ph f g -<< (ph, x)+{-# NOINLINE compositeStep #-}++compositeStep' :: ArrowApply a => +              Phase -> +              StepType a b d -> StepType a d c -> StepType a b c+             +compositeStep' Sweep f g = proc (_, x) ->+  do+    (_, r1, pa') <- f -< (Suspend, x)+    (ph2, r2, pb') <- g -<< (Sweep, r1)+    cont ph2 -<< (r2, pa', pb', x)+  where+    cont Feed = arr $ \(r, pa, pb, _) -> (Feed, r, pa >>> pb)+    cont Sweep = arr $ \(r, pa, pb, _) -> (Sweep, r, pa >>> pb)+    cont Suspend = proc (r, pa, pb, x) ->+      do+        (ph1, r1, pa') <- step pa -<< (Sweep, x)+        (ph2, r2, pb') <-+            (if ph1 == Feed+                then+                  step pb+                else+                  arr $ const (Suspend, r, pb))+                      -<< (ph1, r1)+        returnA -< (ph2, r2, pa' >>> pb')++compositeStep' ph f g = proc (_, x) ->+  do+    (ph1, r1, pa') <- f -< (ph, x)+    (ph2, r2, pb') <- g -<< (ph1, r1)+    returnA -< (ph2, r2, pa' >>> pb')++-- rules+{-# RULES+"ProcessA: id/*"+    forall g. compositeStep idStep g = g+"ProcessA: */id"+    forall f. compositeStep f idStep = f++"ProcessA: concat/concat" +    forall f g h. compositeStep (compositeStep f g) h = compositeStep f (compositeStep g h)++"ProcessA: dimap/dimap"+    forall f g h i j. dimapStep f j (dimapStep g i h)  = dimapStep (g . f) (j . i) h+"ProcessA: dimap/arr"+    forall f g h. dimapStep f h (arrStep g) = arrStep (h . g . f)++"ProcessA: arr***/par"+    forall f1 f2 g1 g2 h. compositeStep (parStep f1 (arrStep f2)) (compositeStep (parStep g1 g2) h) =+        compositeStep (parStep (compositeStep f1 g1) (dimapStep f2 id g2)) h+"ProcessA: arr***/par-2"+    forall f1 f2 g1 g2. compositeStep (parStep f1 (arrStep f2)) (parStep g1 g2) =+        parStep (compositeStep f1 g1) (dimapStep f2 id g2)+"ProcessA: par/***arr"+    forall f1 f2 g1 g2 h. compositeStep (parStep f1 f2) (compositeStep (parStep (arrStep g1) g2) h) =+        compositeStep (parStep (dimapStep id g1 f1) (compositeStep f2 g2)) h+"ProcessA: par/***arr-2"+    forall f1 f2 g1 g2. compositeStep (parStep f1 f2) (parStep (arrStep g1) g2) =+        parStep (dimapStep id g1 f1) (compositeStep f2 g2)++"ProcessA: first/par"+    forall f1 g1 g2 h. compositeStep (parStep f1 idStep) (compositeStep (parStep g1 g2) h) =+        compositeStep (parStep (compositeStep f1 g1) g2) h+"ProcessA: first/par-2"+    forall f1 g1 g2. compositeStep (parStep f1 idStep) (parStep g1 g2) =+        parStep (compositeStep f1 g1) g2+"ProcessA: par/second"+    forall f1 f2 g2 h. compositeStep (parStep f1 f2) (compositeStep (parStep idStep g2) h) =+        compositeStep (parStep f1 (compositeStep f2 g2)) h+"ProcessA: par/second-2"+    forall f1 f2 g2. compositeStep (parStep f1 f2) (parStep idStep g2) =+        parStep f1 (compositeStep f2 g2)++"ProcessA: arr/arr"+    forall f g h. compositeStep (arrStep f) (compositeStep (arrStep g) h) =+        compositeStep (arrStep (g . f)) h+"ProcessA: arr/arr-2"+    forall f g. compositeStep (arrStep f) (arrStep g) = arrStep (g . f)+"ProcessA: arr/*" [1]+    forall f g. compositeStep (arrStep f) g = dimapStep f id g+"ProcessA: */arr" [1]+    forall f g. compositeStep f (arrStep g) = dimapStep id g f+"ProcessA: arr***arr" [0]+    forall f g. parStep (arrStep f) (arrStep g) = arrStep (f *** g)+  #-}++instance+    ArrowApply a => ArrowChoice (ProcessA a)+  where+    left pa@(ProcessA a) = ProcessA $ proc (ph, eth) -> go ph eth -<< ()+      where+        go ph (Left x) = proc _ -> +          do+            (ph', y, pa') <- a -< (ph, x)+            returnA -< (ph', Left y, left pa')+        go ph (Right d) = proc _ -> +            returnA -< (ph `mappend` Suspend, Right d, left pa)++instance+    (ArrowApply a, ArrowLoop a) => ArrowLoop (ProcessA a)+  where+    loop = fitEx (\f -> loop (lp f))+      where+        lp f = proc ((p, x), d) ->+          do+            (q, (y, d')) <- f -< (p, (x, d))+            returnA -< ((q, y), d')+++instance+    (ArrowApply a, ArrowReader r a) => +    ArrowReader r (ProcessA a)+  where+    readState = ProcessA $ proc (ph, dm) ->+      do+        r <- readState -< dm+        returnA -< (ph `mappend` Suspend, r, readState)++    newReader = fitEx nr+      where+        nr f = proc (p, (x, r)) -> newReader f -< ((p, x), r)++instance+    (ArrowApply a, ArrowApply a', ArrowAddReader r a a') =>+    ArrowAddReader r (ProcessA a) (ProcessA a')+  where+    liftReader pa = ProcessA $ proc (ph, x) ->+      do+        (ph', y, pa') <- (| liftReader (step pa -< (ph, x)) |)+        returnA -< (ph', y, liftReader pa')++    elimReader pra = +        ProcessA $ arr pre >>> elimReader (step pra) >>> arr post+      where+        pre (ph, (x, r)) = ((ph, x), r)+        post (ph, x, pra') = (ph, x, elimReader pra')+++    +data Event a = Event a | NoEvent | End deriving (Eq, Show)+++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 monoidal 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+++isNoEvent :: Occasional' a => a -> Bool+isNoEvent = collapse >>> \case { NoEvent -> True; _ -> False }++isEnd :: Occasional' a => a -> Bool+isEnd = collapse >>> \case { End -> True; _ -> False }++{-+isOccasion :: Occasional' a => a -> Bool+isOccasion = collapse >>> \case { Event () -> True; _ -> False }+-}++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++++-- TODO: テスト+condEvent :: Bool -> Event a -> Event a+condEvent _ End = End+condEvent True ev = ev+condEvent False _ = NoEvent++-- TODO: テスト+filterEvent :: (a -> Bool) -> Event a -> Event a+filterEvent cond ev@(Event x) = condEvent (cond x) ev+filterEvent _ ev = ev++-- | 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+    rSwitch (arr $ const noEvent) -< ((), stopped <$ collapse x)++++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+++type PlanT i o m a = F.FT (PlanF i o) m a+type Plan i o a = forall m. Monad m => PlanT i o m a+++yield :: o -> Plan i o ()+yield x = F.liftF $ YieldPF x ()++await :: Plan i o i+await = F.FT $ \pure free -> free (AwaitPF pure (free StopPF))++stop :: Plan i o a+stop = F.liftF $ StopPF+++catchP:: Monad m =>+    PlanT i o m a -> PlanT i o m a -> PlanT i o m a++catchP pl cont = +    F.toFT $ catch' (F.fromFT pl) (F.fromFT cont)++catch' ::+    Monad m =>+    F.FreeT (PlanF t o) m a ->+    F.FreeT (PlanF t o) m a ->+    F.FreeT (PlanF t o) m a++catch' (F.FreeT mf) cont@(F.FreeT mcont) = +    F.FreeT $ mf >>= go+  where+    go (F.Pure a) = return $ F.Pure a+    go (F.Free StopPF) = mcont+    go (F.Free (AwaitPF f ff)) = +        return $ F.Free $ +        AwaitPF (\i -> f i `catch'` cont) (ff `catch'` cont)+    go (F.Free fft) = +        return $ F.Free $ (`catch'` cont) <$> fft+++++constructT :: (Monad m, ArrowApply a) => +              (forall b. m b -> a () b) ->+              PlanT i o m r -> +              ProcessA a (Event i) (Event o)++constructT fit0 pl = ProcessA $ fit' $ F.runFT pl pure free+  where+    fit' ma = proc arg -> do { (evx, pa) <- fit0 ma -< (); modFit evx pa -<< arg }+    +    modFit :: ArrowApply a => Event c -> StepType a b (Event c) -> StepType a b (Event c)+    modFit (Event x) stp = retArrow Feed (Event x) (ProcessA stp)+    modFit End stp = retArrow Feed End (ProcessA stp)+    modFit _ stp = stp++    retArrow ph' evx cont = arr $ \(ph, _) -> +        case ph of+          Suspend -> +              (ph `mappend` Suspend,+               if isEnd evx then End else NoEvent,+               ProcessA $ retArrow ph' evx cont)+          _ -> +              (ph `mappend` ph', evx, cont)++    pure _ = return $ (End, retArrow Suspend End stopped)++    free (AwaitPF f ff) =+      do+        return $ (NoEvent, arr (uncurry (awaitIt f ff)) >>> proc pc -> pc -<< ())++    free (YieldPF y fc) = return $ (Event y, fit' fc)++    free StopPF = return $ (End, retArrow Suspend End stopped)+++    awaitIt f _ Feed (Event x) = proc _ ->+      do+        (evy, stp) <- fit0 (f x) -< ()+        returnA -< (Feed, evy, ProcessA stp)++    awaitIt _ ff Feed End = proc _ ->+      do+        (evy, stp) <- fit0 ff -< ()+        returnA -< (Feed, evy, ProcessA stp)++    awaitIt _ ff Sweep End = proc _ ->+      do+        (evy, stp) <- fit0 ff -< ()+        returnA -< (if not $ isNoEvent evy then Feed else Suspend, evy, ProcessA stp)++    awaitIt f ff ph _ = proc _ ->+        returnA -< (ph `mappend` Suspend, NoEvent, +                    ProcessA $ arr (uncurry (awaitIt f ff)) >>> proc pc -> pc -<< ())+++repeatedlyT :: (Monad m, ArrowApply a) => +              (forall b. m b -> a () b) ->+              PlanT i o m r -> +              ProcessA a (Event i) (Event o)++repeatedlyT f pl = constructT f $ forever pl+++-- for pure+construct :: ArrowApply a =>+             Plan i o t -> +             ProcessA a (Event i) (Event o)+construct pl = constructT (ary0 unArrowMonad) pl++repeatedly :: ArrowApply a =>+              Plan i o t -> +              ProcessA a (Event i) (Event o)+repeatedly pl = construct $ forever pl+++--+-- Switches+--+evMaybePh :: b -> (a->b) -> (Phase, Event a) -> b+evMaybePh _ f (Feed, Event x) = f x+evMaybePh _ f (Sweep, Event x) = f x+evMaybePh d _ _ = d+++{-+type KSwitchLike a b c t =+    ProcessA a b c ->+    ProcessA a (b, ) (Event t) ->+    (ProcessA a b c -> t -> ProcessA a b c) ->+    ProcessA a b c++switchCore ::+    ArrowApply a =>+    KSwitchLike a b c t ->+    ProcessA a b (c, Event t) -> +    (t -> ProcessA a b c) ->+    ProcessA a b c+-}+switchCore ::+    (Arrow cat, Arrow a2, Arrow cat1, Occasional t3) =>+    (t4+     -> a2 (t5, (t6, c1)) c1+     -> (t -> t1 -> cat a (t2, t3))+     -> cat1 a1 (c, b))+     -> t4 -> (t1 -> cat a t2) -> cat1 a1 c++switchCore sw cur cont = sw cur (arr test) cont' >>> arr fst+  where+    test (_, (_, evt)) = evt+    cont' _ t = cont t >>> arr (\y -> (y, noEvent))++switch :: +    ArrowApply a => +    ProcessA a b (c, Event t) -> +    (t -> ProcessA a b c) ->+    ProcessA a b c++switch = switchCore kSwitch+++dSwitch :: +    ArrowApply a => +    ProcessA a b (c, Event t) -> +    (t -> ProcessA a b c) ->+    ProcessA a b c++dSwitch = switchCore dkSwitch+++rSwitch :: +    ArrowApply a => ProcessA a b c -> +    ProcessA a (b, Event (ProcessA a b c)) c++rSwitch cur = ProcessA $ proc (ph, (x, eva)) -> +  do+    let now = evMaybePh cur id (ph, eva)+    (ph', y, new) <-  step now -<< (ph, x)+    returnA -< (ph', y, rSwitch new)+++drSwitch :: +    ArrowApply a => ProcessA a b c -> +    ProcessA a (b, Event (ProcessA a b c)) c++drSwitch cur = ProcessA $ proc (ph, (x, eva)) -> +  do+    (ph', y, new) <- step cur -< (ph, x)+    returnA -< (ph', y, drSwitch (evMaybePh new id (ph, eva)))++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 k = ProcessA $ proc (ph, x) ->+  do+    (ph', y, sf') <- step sf -< (ph, x)+    (phT, evt, test') <- step test -< (ph', (x, y))++    evMaybePh +        (arr $ const (phT, y, kSwitch sf' test' k)) +        (step . (k sf'))+        (phT, evt)+            -<< (phT, x)+++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 k = ProcessA $ proc (ph, x) ->+  do+    (ph', y, sf') <- step sf -< (ph, x)+    (phT, evt, test') <- step test -< (ph', (x, y))+    +    let+        nextA t = k sf' t+        nextB = dkSwitch sf' test' k++    returnA -< (phT, y, evMaybePh nextB nextA (ph, evt))+++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 = ProcessA $ parCore r sfs >>> arr cont+  where+    cont (ph, ys, sfs') = (ph, ys, par r sfs')++parB ::+    (ArrowApply a, Tv.Traversable col) =>+    col (ProcessA a b c) ->+    ProcessA a b (col c)++parB = par broadcast++parCore ::+    (ArrowApply a, Tv.Traversable col) =>+    (forall sf. (b -> col sf -> col (ext, sf))) ->+    col (ProcessA a ext c) ->+    a (Phase, b) (Phase, col c, col (ProcessA a ext c))++parCore r sfs = proc (ph, x) ->+  do+    let input = r x sfs++    ret <- unwrapArrow (Tv.sequenceA (fmap (WrapArrow . appPh) input)) -<< ph++    let ph' = Fd.foldMap getPh ret+        zs = fmap getZ ret+        sfs' = fmap getSf ret++    returnA -< (ph', zs, sfs')++  where+    appPh (y, sf) = proc ph -> step sf -< (ph, y)++    getPh (ph, _, _) = ph+    getZ (_, z, _) = z+    getSf (_, _, sf) = 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 k = ProcessA $ proc (ph, x) ->+  do+    (ph', zs, sfs') <- parCore r sfs -<< (ph, x)+    (phT, evt, test') <- step test -< (ph', (x, zs))++    evMaybePh+        (arr $ const (ph' `mappend` phT, zs, pSwitch r sfs' test' k))+        (step . (k sfs') )+        (phT, evt)+            -<< (ph, x)++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+++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 = ProcessA $ proc (ph, (x, evCont)) ->+  do+    let sfsNew = evMaybePh sfs ($sfs) (ph, evCont)+    (ph', ws, sfs') <- parCore r sfsNew -<< (ph, x)+    returnA -< (ph' `mappend` Suspend, ws, 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++-- `dpSwitch` and `drpSwitch` are not implemented.+++--+-- Unsafe primitives+--++-- | Repeatedly call `p`.+--+-- How many times `p` is called is indefinite.+-- So `p` must satisfy the equation below;+--+-- @p &&& p === p >>> (id &&& id)@+unsafeSteady ::+    ArrowApply a =>+    a b c ->+    ProcessA a b c+unsafeSteady f =+    fitEx+        (\id' ->+            arr (\(p, x)->((p, ()), x)) >>>+            (id' *** f) >>>+            arr (\((q, ()), y)->(q, y)))+        Cat.id+      +    +-- | 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 $ proc (ph, x) -> handle ph -<< x+    +    handle Suspend =+        arr $ const (Suspend, NoEvent, go)++    handle ph = proc x ->+      do+        ys <- p -< x+        let ph' = if nullFd ys then Suspend else Feed+        returnA -< (ph `mappend` ph', Event ys, go)++    fork = repeatedly $ await >>= Fd.mapM_ yield++    nullFd = getAll . Fd.foldMap (\_ -> All False)++++--+-- Running+--+--+-- Utilities+--+while_ ::+    Monad m =>+    m Bool -> m a -> m ()+while_ cond body =+  do+    b <- cond+    if b+        then body >> while_ cond body+        else return ()++-- | Monoid wrapper+data WithEnd r = WithEnd { +    getRWE :: r,+    getContWE :: Bool+  }++instance+    Monoid r => Monoid (WithEnd r)+  where+    mempty = WithEnd mempty True+    WithEnd x True `mappend` WithEnd y b = WithEnd (x `mappend` y) b+    mx@(WithEnd _ False) `mappend` _ = mx+++--+-- 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 => +    i -> i -> RM a i o 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++feed :: +    Monad m => +    i -> RM a (Event i) o m Bool+feed x = feed_ (Event x) NoEvent+++{-+finalizeE :: +    Monad m => +    RM a (Event i) o m Bool+finalizeE = feed_ End End+-}++freeze ::+    Monad m =>+    RM a i o m (ProcessA a i o)+freeze = gets freezeRI+    ++sweep :: +    Monad m =>+    RM a i o m o+sweep =+  do+    pa <- freeze+    fit0 <- gets getFitRI+    ph <- gets getPhaseRI+    x <- if ph == Feed+        then gets getInputRI+        else gets getPaddingRI+    +    (ph', y, pa') <- lift $ fit0 (step pa) (ph, x)+    +    ri <- get+    put $ ri {+        freezeRI = +            pa',+        getPhaseRI = +            if ph' == Feed then Sweep else ph'+      }++    return y+++sweepAll :: +    (ArrowApply a, Monoid r, Monad m) =>+    (o->r) ->+    WriterT (WithEnd r) (RM a i (Event o) m) ()+sweepAll outpre = +        while_ +            ((not . (== Suspend)) `liftM` lift (gets getPhaseRI)) $+          do+            evx <- lift sweep+            case evx+              of+                Event x ->+                    tell (WithEnd (outpre x) True)+                NoEvent ->+                    return ()+                End ->+                    tell (WithEnd mempty False)+++-- | Run a machine with results concatenated in terms of a monoid.+runOn ::+    (ArrowApply a, Monoid r) =>+    (c -> r) ->+    ProcessA a (Event b) (Event c) ->+    a [b] r+runOn outpre pa0 = unArrowMonad $ \xs ->+  do+    wer <- runRM arrowMonad pa0 $ execWriterT $ +      do+        go xs+        _ <- lift (feed_ End End)+        sweepAll outpre+    return $ getRWE wer++  where+    go xs =+      do+        (_, wer) <- listen $ sweepAll outpre+        if getContWE wer then cont xs else return ()++    cont [] = return ()++    cont (x:xs) =+      do+        _ <- lift $ feed x+        go xs+++-- | Run a machine.+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 :: +    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, -- [a] or Maybe a+        hasConsumed :: Bool,+        hasStopped :: Bool+      }+    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 suspended.+stepRun :: +    ArrowApply a =>+    ProcessA a (Event b) (Event c) ->+    a b (ExecInfo [c], ProcessA a (Event b) (Event c))++stepRun pa0 = unArrowMonad $ \x ->+  do+    (pa, wer)  <- runRM arrowMonad pa0 $ runWriterT $ +      do+        sweepAll singleton+        _ <- lift $ feed x+        sweepAll singleton+        lift $ freeze+    return $ (retval wer, pa)++  where+    singleton x = Endo (x:)++    retval WithEnd {..} = ExecInfo {+        yields = appEndo getRWE [], +        hasConsumed = True, +        hasStopped = not getContWE+      }++-- | 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 $ feed x+        modify $ \ri -> ri { hasConsumed = csmd }+                             +        evo <- lift sweep+        +        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 }  
src/Control/Arrow/Machine/Utils.hs view
@@ -2,20 +2,18 @@ {-# LANGUAGE Arrows #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-}  module     Control.Arrow.Machine.Utils       (         -- * AFRP-like utilities-        delay,         hold,         accum,         edge,         passRecent,         withRecent,-        feedback1,-        feedback,          -- * Switches         -- | Switches inspired by Yampa library.@@ -47,6 +45,7 @@         anytime,         par,         parB,+        now,         onEnd,         cycleDelay        )@@ -54,43 +53,24 @@  import Prelude hiding (filter) -import Data.Monoid (mappend, mconcat)-import Data.Tuple (swap)+import Data.Maybe (fromMaybe) import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Foldable as Fd-import qualified Data.Traversable as Tv import qualified Control.Category as Cat-import Control.Monad.Reader (ask)-import Control.Monad (liftM, forever) import Control.Monad.Trans+import Control.Monad.State import Control.Arrow import Control.Arrow.Operations (ArrowState(..))-import Control.Arrow.Transformer.State (ArrowAddState(..))+import Control.Arrow.Transformer.State (ArrowAddState(..), StateArrow()) import Control.Applicative-import Debug.Trace -import Control.Arrow.Machine.Types-import Control.Arrow.Machine.Event-import Control.Arrow.Machine.Event.Internal (Event(..)) import Control.Arrow.Machine.ArrowUtil+import Control.Arrow.Machine.Types -import qualified Control.Arrow.Machine.Plan as Pl-import Control.Arrow.Machine.Exception   -delay ::-    (ArrowApply a, Occasional b) => ProcessA a b b -delay = join >>> delayImpl >>> split-  where-    delayImpl = Pl.repeatedly $-      do-        mx <- liftM Just Pl.await `catch` return Nothing-        Pl.yield noEvent-        maybe Pl.stop Pl.yield mx-- hold ::      ArrowApply a => b -> ProcessA a (Event b) b {-@@ -101,34 +81,36 @@ -} hold old = proc evx ->    do-    rSwitch (arr $ const old) -< ((), arr . const <$> evx)+    rSwitch (pure old) -< ((), pure <$> evx)  accum ::     ArrowApply a => b -> ProcessA a (Event (b->b)) b-accum old = ProcessA $ proc (ph, evf) ->-  do-    let new = fromEvent id evf old-    returnA -< (ph `mappend` Suspend, new, accum new)+accum x = switch (pure x &&& arr (($x)<$>)) accum'+  where+    accum' y = dSwitch (pure y &&& Cat.id) (const (accum y))+    edge ::      (ArrowApply a, Eq b) =>     ProcessA a b (Event b) -edge = ProcessA $ impl Nothing +edge = encloseState (unsafeExhaust impl) Nothing   where-    impl mvx = proc (ph, x) -> +    impl ::+        (ArrowApply a, Eq b) =>+        StateArrow (Maybe b) a b (Maybe b)+    impl = proc x ->       do-        let equals = maybe False (==x) mvx-            isActive = not $ ph == Suspend-        returnA -< if (not equals) && isActive-          then -            (Feed, Event x, ProcessA $ impl (Just x))-          else-            (ph `mappend` Suspend, NoEvent, ProcessA $ impl mvx)+        mprv <- fetch -< ()+        store -< Just x+        returnA -<+            case mprv+              of+                Just prv -> if prv == x then Nothing else Just x+                Nothing -> Just x  {-# DEPRECATED passRecent, withRecent "Use `hold` instead" #-} infixr 9 `passRecent`-infixr 9 `feedback`  passRecent ::      (ArrowApply a, Occasional o) =>@@ -156,316 +138,75 @@       _ -> returnA -< noEvent  -{-# DEPRECATED feedback1, feedback "Use Pump instead" #-}--- |Event version of loop (member of `ArrowLoop`).             --- Yielding an event to feedback output always creates a new process cycle.--- So be careful to make an infinite loop.-feedback1 ::-    (ArrowApply a, Occasional d) =>-    ProcessA a (e, AS d) (c, d) ->-    ProcessA a (AS e) c-feedback1 pa = ProcessA $ proc (ph, ase) ->-  do-    (ph', (y, d), pa') <- step pa -< (ph, (fromAS ase, toAS noEvent))-    returnA -< (ph', y, cont ph' d pa')-  where-    cont phPrev d paC -        | isOccasion d = ProcessA $ proc (ph, ase) ->-          do-            let -              (dIn, dOut, phPv2, phCur) = -                if ph == Suspend-                  then-                    (noEvent, const d, const phPrev, Suspend)-                  else-                    (d, id, id, ph `mappend` Feed) -            (ph', (y, d'), pa') <- step paC -< (phCur, (fromAS ase, toAS dIn))-            returnA -< (ph', y, cont (phPv2 ph') (dOut d') pa') -        | isEnd d && phPrev == Feed = ProcessA $ proc (ph, ase) ->-          do-            (ph', (y, _), pa') <- step paC -< (ph, (fromAS ase, toAS end))-            returnA -< (ph', y, proc asx -> arr fst <<< pa' -< (fromAS asx, toAS end)) -        | otherwise = feedback1 paC ---- |Artificially split into two arrow to use binary operator notation--- rather than banana brackets.-feedback ::-    (ArrowApply a, Occasional d) =>-    ProcessA a (e, AS d) b ->-    ProcessA a (e, AS b) (c, d) ->-    ProcessA a (AS e) c-feedback pa pb = -    feedback1 $ proc (ase, x) -> -      do -        y <- pa -< (ase, x)-        pb -< (ase, toAS y)-- ----- Switches----evMaybePh :: b -> (a->b) -> (Phase, Event a) -> b-evMaybePh _ f (Feed, Event x) = f x-evMaybePh _ f (Sweep, Event x) = f x-evMaybePh d _ _ = d---switchCore sw cur cont = sw cur (arr test) cont' >>> arr fst-  where-    test (_, (_, evt)) = evt-    cont' _ t = cont t >>> arr (\y -> (y, noEvent))--switch :: -    ArrowApply a => -    ProcessA a b (c, Event t) -> -    (t -> ProcessA a b c) ->-    ProcessA a b c--switch = switchCore kSwitch---dSwitch :: -    ArrowApply a => -    ProcessA a b (c, Event t) -> -    (t -> ProcessA a b c) ->-    ProcessA a b c--dSwitch = switchCore dkSwitch---rSwitch :: -    ArrowApply a => ProcessA a b c -> -    ProcessA a (b, Event (ProcessA a b c)) c--rSwitch cur = ProcessA $ proc (ph, (x, eva)) -> -  do-    let now = evMaybePh cur id (ph, eva)-    (ph', y, new) <-  step now -<< (ph, x)-    returnA -< (ph', y, rSwitch new)---drSwitch :: -    ArrowApply a => ProcessA a b c -> -    ProcessA a (b, Event (ProcessA a b c)) c--drSwitch cur = ProcessA $ proc (ph, (x, eva)) -> -  do-    (ph', y, new) <- step cur -< (ph, x)-    -    returnA -< (ph', y, next new eva)--  where-    next _ (Event af) = drSwitch af-    next af _ = drSwitch af---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 k = ProcessA $ proc (ph, x) ->-  do-    (ph', y, sf') <- step sf -< (ph, x)-    (phT, evt, test') <- step test -< (ph', (x, y))--    evMaybePh -        (arr $ const (phT, y, kSwitch sf' test' k)) -        (step . (k sf'))-        (phT, evt)-            -<< (phT, x)---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 k = ProcessA $ proc (ph, x) ->-  do-    (ph', y, sf') <- step sf -< (ph, x)-    (phT, evt, test') <- step test -< (ph', (x, y))-    -    let-        nextA t = k sf' t-        nextB = dkSwitch sf' test' k--    returnA -< (phT, y, evMaybe nextB nextA evt)---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 = ProcessA $ parCore r sfs >>> arr cont-  where-    cont (ph, ys, sfs') = (ph, ys, par r sfs')--parB ::-    (ArrowApply a, Tv.Traversable col) =>-    col (ProcessA a b c) ->-    ProcessA a b (col c)--parB = par broadcast--parCore ::-    (ArrowApply a, Tv.Traversable col) =>-    (forall sf. (b -> col sf -> col (ext, sf))) ->-    col (ProcessA a ext c) ->-    a (Phase, b) (Phase, col c, col (ProcessA a ext c))--parCore r sfs = proc (ph, x) ->-  do-    let input = r x sfs--    ret <- unwrapArrow (Tv.sequenceA (fmap (WrapArrow . appPh) input)) -<< ph--    let ph' = Fd.foldMap getPh ret-        zs = fmap getZ ret-        sfs' = fmap getSf ret--    returnA -< (ph', zs, sfs')--  where-    appPh (y, sf) = proc ph -> step sf -< (ph, y)--    getPh (ph, _, _) = ph-    getZ (_, z, _) = z-    getSf (_, _, sf) = 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 k = ProcessA $ proc (ph, x) ->-  do-    (ph', zs, sfs') <- parCore r sfs -<< (ph, x)-    (phT, evt, test') <- step test -< (ph', (x, zs))--    evMaybePh-        (arr $ const (ph' `mappend` phT, zs, pSwitch r sfs' test' k))-        (step . (k sfs') )-        (phT, evt)-            -<< (ph, x)--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---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 = ProcessA $ proc (ph, (x, evCont)) ->-  do-    let sfsNew = evMaybePh sfs ($sfs) (ph, evCont)-    (ph', ws, sfs') <- parCore r sfsNew -<< (ph, x)-    returnA -< (ph' `mappend` Suspend, ws, 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---- `dpSwitch` and `drpSwitch` are not implemented.----- -- State arrow -- peekState ::     (ArrowApply a, ArrowState s a) =>     ProcessA a e s-peekState = ProcessA $ proc (ph, dm) ->-  do-    s <- fetch -< dm-    returnA -< (ph `mappend` Suspend, s, peekState)+peekState = unsafeSteady fetch +-- Should be exported?+exposeState ::+    (ArrowApply a, ArrowApply a', ArrowAddState s a a') =>+    ProcessA a b c ->+    ProcessA a' (b, s) (c, s)+exposeState = fitEx es+  where+    es f = proc (p, (x, s)) ->+      do+        ((q, y), s') <- elimState f -< ((p, x), s)+        returnA -< (q, (y, s'))+ encloseState ::-    (ArrowApply a, ArrowAddState s a a') =>+    (ArrowApply a, ArrowApply a', ArrowAddState s a a') =>     ProcessA a b c ->     s ->     ProcessA a' b c-encloseState pa s = ProcessA $ proc (ph, x) ->-  do-    ((ph', y, pa'), s') <- elimState (step pa) -< ((ph, x), s)-    returnA -< (ph', y, encloseState pa' s')+encloseState pa s = loop' s (exposeState pa)  -- -- other utility arrow  -- |Make two event streams into one. -- Actually `gather` is more general and convenient;--- @---   ... <- tee -< (e1, e2)--- @+-- +-- @... \<- tee -\< (e1, e2)@+--  -- is equivalent to--- @---   ... <- gather -< [Left <$> e1, Right <$> e2]--- @+-- +-- @... \<- gather -\< [Left \<$\> e1, Right \<$\> e2]@+--  tee ::     ArrowApply a => ProcessA a (Event b1, Event b2) (Event (Either b1 b2))-tee = join >>> go-  where-    go = Pl.repeatedly $ -      do-        (evx, evy) <- Pl.await-        evMaybe (return ()) (Pl.yield . Left) evx-        evMaybe (return ()) (Pl.yield . Right) evy+tee = proc (e1, e2) -> gather -< [Left <$> e1, Right <$> e2]  + sample ::     ArrowApply a =>     ProcessA a (Event b1, Event b2) [b1]-sample = join >>> Pl.construct (go id) >>> hold []+{-+sample = join >>> construct (go id) >>> hold []   where     go l =        do-        (evx, evy) <- Pl.await `catch` return (NoEvent, End)+        (evx, evy) <- await `catch` return (NoEvent, End)         let l2 = evMaybe l (\x -> l . (x:)) evx         if isEnd evy           then           do-            Pl.yield $ l2 []-            Pl.stop+            yield $ l2 []+            stop           else             return ()-        evMaybe (go l2) (\_ -> Pl.yield (l2 []) >> go id) evy+        evMaybe (go l2) (\_ -> yield (l2 []) >> go id) evy+-}+sample = undefined  -- |Make multiple event channels into one. -- If simultaneous events are given, lefter one is emitted earlier.@@ -477,28 +218,31 @@     singleton x = x NonEmpty.:| []  -- | Provides a source event stream.--- A dummy input event stream is needed. +-- A dummy input event stream is needed.+--    -- @ --   run af [...] -- @+--    -- is equivalent to+-- -- @ --   run (source [...] >>> af) (repeat ()) -- @ source ::     (ArrowApply a, Fd.Foldable f) =>     f c -> ProcessA a (Event b) (Event c)-source l = Pl.construct $ Fd.mapM_ yd l+source l = construct $ Fd.mapM_ yd l   where-    yd x = Pl.await >> Pl.yield x+    yd x = await >> yield x  -- |Given an array-valued event and emit it's values as inidvidual events. fork ::     (ArrowApply a, Fd.Foldable f) =>     ProcessA a (Event (f b)) (Event b) -fork = Pl.repeatedly $ -    Pl.await >>= Fd.mapM_ Pl.yield+fork = repeatedly $ +    await >>= Fd.mapM_ yield  -- |Executes an action once per an input event is provided. anytime :: @@ -506,18 +250,22 @@     a b c ->     ProcessA a (Event b) (Event c) -anytime action = Pl.repeatedlyT (ary0 unArrowMonad) $+anytime action = repeatedlyT (ary0 unArrowMonad) $   do-    x <- Pl.await+    x <- await     ret <- lift $ arrowMonad action x-    Pl.yield ret+    yield ret  -filter cond = Pl.repeatedlyT (ary0 unArrowMonad) $+filter ::+    ArrowApply a =>+    a b Bool ->+    ProcessA a (Event b) (Event b)+filter cond = repeatedlyT (ary0 unArrowMonad) $   do-    x <- Pl.await+    x <- await     b <- lift $ arrowMonad cond x-    if b then Pl.yield x else return ()+    if b then yield x else return ()   echo :: @@ -526,23 +274,42 @@  echo = filter (arr (const True)) +now ::+    ArrowApply a =>+    ProcessA a b (Event ())+now = arr (const noEvent) >>> go+  where+    go = construct $+        yield () >> forever await  onEnd ::-    (ArrowApply a, Occasional b) =>+    (ArrowApply a, Occasional' b) =>     ProcessA a b (Event ())-onEnd = join >>> go+onEnd = arr collapse >>> go   where-    go = Pl.repeatedly $-        Pl.await `catch` (Pl.yield () >> Pl.stop)+    go = repeatedly $+        await `catchP` (yield () >> stop)      -- |Observe a previous value of a signal. -- Tipically used with rec statement. cycleDelay ::     ArrowApply a => ProcessA a b b-cycleDelay = ProcessA $ arr begin+cycleDelay =+    encloseState impl (Nothing, Nothing)   where-    begin (ph, x) = (ph `mappend` Suspend, x, ProcessA $ arr (go x))-    go cur (Sweep, x) = (Suspend, cur, ProcessA $ arr (go x))-    go cur (ph, _) = (ph, cur, ProcessA $ arr (go cur))+    impl :: ArrowApply a => ProcessA (StateArrow (Maybe b, Maybe b) a) b b+    impl = proc x ->+      do+        -- Load stored value when backtracking reaches here.+        (_, stored) <- peekState -< ()+        unsafeExhaust (app >>> arr (const Nothing)) -< appStore stored +        -- Repeat current value.+        (current, _) <- peekState -< ()+        let x0 = fromMaybe x current+        unsafeSteady store -< (Just x0, Just x)+        returnA -< x0++    appStore (Just x) = (proc _ -> store -< (Just x, Nothing), ())+    appStore _ = (Cat.id, ())     
test/RandomProc.hs view
@@ -16,6 +16,8 @@ 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@@ -104,9 +106,8 @@  mkProcJ (PjFst pg) = arr fst mkProcJ (PjSnd pg) = arr snd-mkProcJ (PjSum pg) = arr go-  where-    go (evx, evy) = (+ fromEvent 0 evy) <$> evx+mkProcJ (PjSum pg) = proc (evx, evy) ->+    returnA -< getSum <$> foldMap (Sum <$>) [evx, evy]   stateProc :: MyProcT (Event a) (Event b) -> [a] -> ([b], [Int])@@ -159,13 +160,11 @@ instance     (TestOut a, TestOut b) => TestOut (a, b)   where-    output = output *** output >>> P.join >>> mc >>> P.split-      where-        mc = repeatedly $-          do-            (x, y) <- await-            yield x-            yield y+    output = proc (x1, x2) ->+      do+        y1 <- output -< x1+        y2 <- output -< x2+        gather -< [y1, y2]  instance     (TestIn a, TestIn b) => @@ -174,7 +173,7 @@     input = proc evx ->       do         -- 一個前の値で分岐してみる-        b <- hold True <<< delay -< +        b <- cycleDelay <<< hold True -<                 (\x -> x `mod` 2 == 0) <$> evx          if b@@ -182,7 +181,6 @@             arr Left <<< input -< evx           else             arr Right <<< input -< evx-  instance     (TestOut a, TestOut b) => TestOut (Either a b)
test/spec.hs view
@@ -4,6 +4,8 @@ {-# LANGUAGE TypeSynonymInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE FlexibleContexts #-}
+
 module
     Main
 where
@@ -37,7 +39,6 @@     plans
     utility
     switches
-    operator
     execution
     loopUtil
 
@@ -220,14 +221,16 @@       do
         it "can be used with rec statement(pure)" $
           let
-              a = proc x ->
+              a = proc ev ->
                 do
-                  rec l <- returnA -< evMaybe [] (:l) x
-                  returnA -< l <$ x
+                  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 "can be used with rec statement(macninery)" $
           let
               mc = anytime Cat.id
@@ -254,6 +257,7 @@                         z <- hold 0 <<< delay -< y
                     returnA -< y
             run pa [1, 10] `shouldBe` [1, 2, 12, 24]
+-}
 
     describe "Rules for ArrowLoop" $
       do
@@ -340,7 +344,7 @@       do
         let pl2 =
               do
-                x <- await `catch` (yield 1 >> stop)
+                x <- await `catchP` (yield 1 >> stop)
                 yield x
                 y <- await 
                 yield y
@@ -351,12 +355,12 @@ 
 utility =
   do
-    describe "delay" $
+    describe "edge" $
       do
-        it "delays input" $
+        it "detects edges of input behaviour" $
           do
-            run (arr (\x->(x,x)) >>> first delay >>> arr fst) [0, 1, 2] `shouldBe` [0, 1, 2]
-            run (arr (\x->(x,x)) >>> first delay >>> arr snd) [0, 1, 2] `shouldBe` [0, 1, 2]
+            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
@@ -382,29 +386,6 @@                     returnA -< x <$ ed
             run pa [1..4] `shouldBe` [4]
 
-    describe "sample" $
-      do
-        it "samples events in terms of the 2nd input." $
-          do
-            let
-                pa = proc evx ->
-                  do
-                    evy <- fork -< (\x -> [x, x]) <$> evx
-                    ys <- sample -< (evy, evx)
-                    ed <- onEnd -< evy
-                    outEv <- gather -< [() <$ evx, ed]
-                    returnA -< ys <$ outEv
-            Control.Monad.join (run pa [1..3]) `shouldBe` [1, 1, 2, 2, 3, 3]
-
-        it "correctly pushes simultaneous events into the same time." $
-          do
-            let 
-                pa = proc evx ->
-                  do
-                    l <- sample -< (evx, evx)
-                    returnA -< l <$ evx
-            run pa [1..3] `shouldBe` [[1], [2], [3]]
-
     describe "gather" $
       do
         it "correctly handles the end" $
@@ -470,46 +451,6 @@             ret `shouldBe` [7, 2, 6, 18, 21]
             retD `shouldBe` [7, 3, 6, 12, 21]
 
-
-operator = describe "Operators on ProcessA"$
-  do
-    describe "feedback" $
-      do
-        it "acts like local variable with hold." $
-          do
-            let 
-                pa = proc evx ->
-                  do
-                    (\evy -> hold 10 -< evy)
-                      `feedback` \y ->
-                      do
-                        returnA -< ((+y) <$> evx, (y+1) <$ evx)
-            run pa [1, 2, 3] `shouldBe` [11, 13, 15]
-
-        it "correctly handles stream end." $
-          do
-            let 
-                pa = proc x -> 
-                    (\asx -> returnA -< asx)
-                  `feedback` 
-                    (\asy -> returnA -< (asy::Event Int, x))
-                comp = mkProc (PgPush PgStop) >>> pa
-            stateProc comp [0, 0] `shouldBe` ([], [0])
-
-        it "correctly handles stream end.(2)" $
-          do
-            pendingWith "now many utilities behave incorrectly at the end of stream."
-{-
-            let pa = proc x -> (| feedback1 (\y -> returnA -< (y::Event Int, x)) |)
-            let comp = mkProc (PgPush PgStop) >>> pa >>> mkProc (PgDouble PgNop)
-            stateProc comp [0, 0] `shouldBe` ([], [0])
-
-        prop "delays the feedback input." $ \cond ->
-            let 
-                equiv = mkEquivTest cond
-              in
-                delay `equiv` proc x -> (| feedback1 (\y -> returnA -< (y::Event Int, x)) |)
--}
 
 execution = describe "Execution of ProcessA" $
     do