module
Control.Arrow.Machine.Plan
(
PlanT,
Plan,
await,
yield,
stop,
stopped,
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
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