machinecell-4.0.1: Arrow based stream transducers

Safe HaskellTrustworthy
LanguageHaskell2010

Control.Arrow.Machine.Types

Contents

Synopsis

Stream transducer type

data ProcessT m b c Source #

The stream transducer arrow.

To construct ProcessT instances, use Plan, arr, functions declared in Utils, or arrow combinations of them.

See an introduction at Control.Arrow.Machine documentation.

Instances

Monad m => Arrow (ProcessT m) Source # 

Methods

arr :: (b -> c) -> ProcessT m b c #

first :: ProcessT m b c -> ProcessT m (b, d) (c, d) #

second :: ProcessT m b c -> ProcessT m (d, b) (d, c) #

(***) :: ProcessT m b c -> ProcessT m b' c' -> ProcessT m (b, b') (c, c') #

(&&&) :: ProcessT m b c -> ProcessT m b c' -> ProcessT m b (c, c') #

Monad m => ArrowChoice (ProcessT m) Source # 

Methods

left :: ProcessT m b c -> ProcessT m (Either b d) (Either c d) #

right :: ProcessT m b c -> ProcessT m (Either d b) (Either d c) #

(+++) :: ProcessT m b c -> ProcessT m b' c' -> ProcessT m (Either b b') (Either c c') #

(|||) :: ProcessT m b d -> ProcessT m c d -> ProcessT m (Either b c) d #

Monad m => ArrowLoop (ProcessT m) Source # 

Methods

loop :: ProcessT m (b, d) (c, d) -> ProcessT m b c #

Monad m => Profunctor (ProcessT m) Source # 

Methods

dimap :: (a -> b) -> (c -> d) -> ProcessT m b c -> ProcessT m a d #

lmap :: (a -> b) -> ProcessT m b c -> ProcessT m a c #

rmap :: (b -> c) -> ProcessT m a b -> ProcessT m a c #

(#.) :: Coercible * c b => (b -> c) -> ProcessT m a b -> ProcessT m a c #

(.#) :: Coercible * b a => ProcessT m b c -> (a -> b) -> ProcessT m a c #

Monad m => Category * (ProcessT m) Source # 

Methods

id :: cat a a #

(.) :: cat b c -> cat a b -> cat a c #

Monad m => Functor (ProcessT m i) Source # 

Methods

fmap :: (a -> b) -> ProcessT m i a -> ProcessT m i b #

(<$) :: a -> ProcessT m i b -> ProcessT m i a #

Monad m => Applicative (ProcessT m i) Source # 

Methods

pure :: a -> ProcessT m i a #

(<*>) :: ProcessT m i (a -> b) -> ProcessT m i a -> ProcessT m i b #

liftA2 :: (a -> b -> c) -> ProcessT m i a -> ProcessT m i b -> ProcessT m i c #

(*>) :: ProcessT m i a -> ProcessT m i b -> ProcessT m i b #

(<*) :: ProcessT m i a -> ProcessT m i b -> ProcessT m i a #

(Monad m, Semigroup o) => Semigroup (ProcessT m i o) Source # 

Methods

(<>) :: ProcessT m i o -> ProcessT m i o -> ProcessT m i o #

sconcat :: NonEmpty (ProcessT m i o) -> ProcessT m i o #

stimes :: Integral b => b -> ProcessT m i o -> ProcessT m i o #

(Monad m, Monoid o) => Monoid (ProcessT m i o) Source # 

Methods

mempty :: ProcessT m i o #

mappend :: ProcessT m i o -> ProcessT m i o -> ProcessT m i o #

mconcat :: [ProcessT m i o] -> ProcessT m i o #

type ProcessA a = ProcessT (ArrowMonad a) Source #

Isomorphic to ProcessT when a is ArrowApply.

Event type and utility

class Occasional' a where Source #

Signals that can be absent(NoEvent) or end. For composite structure, collapse can be defined as monoid sum of all member occasionals.

Minimal complete definition

collapse

Methods

collapse :: a -> Event () Source #

Instances

class Occasional' a => Occasional a where Source #

Occasional signals with creation methods.

Minimal complete definition

burst

Methods

burst :: Event Void -> a Source #

Instances

Occasional (Event a) Source # 

Methods

burst :: Event Void -> Event a Source #

(Occasional a, Occasional b) => Occasional (a, b) Source # 

Methods

burst :: Event Void -> (a, b) Source #

data Event a Source #

Discrete events on a time line. Created and consumed by various transducers.

Instances

Functor Event Source # 

Methods

fmap :: (a -> b) -> Event a -> Event b #

(<$) :: a -> Event b -> Event a #

Semigroup a => Semigroup (Event a) Source # 

Methods

(<>) :: Event a -> Event a -> Event a #

sconcat :: NonEmpty (Event a) -> Event a #

stimes :: Integral b => b -> Event a -> Event a #

Semigroup a => Monoid (Event a) Source # 

Methods

mempty :: Event a #

mappend :: Event a -> Event a -> Event a #

mconcat :: [Event a] -> Event a #

Occasional (Event a) Source # 

Methods

burst :: Event Void -> Event a Source #

Occasional' (Event a) Source # 

Methods

collapse :: Event a -> Event () Source #

Monad m => MonadYield (Evolution i (Event a) m) a Source # 

Methods

yield :: a -> Evolution i (Event a) m () Source #

(Monad m, Occasional o) => MonadAwait (Evolution (Event a) o m) a Source # 

Methods

await :: Evolution (Event a) o m a Source #

filterEvent :: Arrow ar => (a -> Bool) -> ar (Event a) (Event a) Source #

filterJust :: Arrow ar => ar (Event (Maybe a)) (Event a) Source #

filterLeft :: Arrow ar => ar (Event (Either a b)) (Event a) Source #

Split an event stream.

>>> run (filterLeft) [Left 1, Right 2, Left 3, Right 4]
[1,3]

filterRight :: Arrow ar => ar (Event (Either a b)) (Event b) Source #

Split an event stream.

>>> run filterRight [Left 1, Right 2, Left 3, Right 4]
[2,4]

splitEvent :: Arrow ar => ar (Event (Either a b)) (Event a, Event b) Source #

Split an event stream.

>>> run (splitEvent >>> arr fst) [Left 1, Right 2, Left 3, Right 4]
[1,3]
>>> run (splitEvent >>> arr snd) [Left 1, Right 2, Left 3, Right 4]
[2,4]

evMap :: Arrow a => (b -> c) -> a (Event b) (Event c) Source #

Alias of "arr . fmap"

While "ProcessT a (Event b) (Event c)" means a transducer from b to c, function b->c can be lifted into a transducer by fhis function.

But in most cases you needn't call this function in proc-do notations, because arrs are completed automatically while desugaring.

For example,

proc x -> returnA -< f <$> x

is equivalent to

evMap f

Coroutine monad

Procedural coroutine monad that can await or yield values.

Coroutines can be encoded to machines by constructT or so on and then put into ProcessT compositions.

newtype PlanT i o m a Source #

Constructors

PlanT 

Fields

Instances

MonadWriter w m => MonadWriter w (PlanT i o m) Source # 

Methods

writer :: (a, w) -> PlanT i o m a #

tell :: w -> PlanT i o m () #

listen :: PlanT i o m a -> PlanT i o m (a, w) #

pass :: PlanT i o m (a, w -> w) -> PlanT i o m a #

MonadState s m => MonadState s (PlanT i o m) Source # 

Methods

get :: PlanT i o m s #

put :: s -> PlanT i o m () #

state :: (s -> (a, s)) -> PlanT i o m a #

MonadReader r m => MonadReader r (PlanT i o m) Source # 

Methods

ask :: PlanT i o m r #

local :: (r -> r) -> PlanT i o m a -> PlanT i o m a #

reader :: (r -> a) -> PlanT i o m a #

MonadTrans (PlanT i o) Source # 

Methods

lift :: Monad m => m a -> PlanT i o m a #

Monad (PlanT i o m) Source # 

Methods

(>>=) :: PlanT i o m a -> (a -> PlanT i o m b) -> PlanT i o m b #

(>>) :: PlanT i o m a -> PlanT i o m b -> PlanT i o m b #

return :: a -> PlanT i o m a #

fail :: String -> PlanT i o m a #

Functor (PlanT i o m) Source # 

Methods

fmap :: (a -> b) -> PlanT i o m a -> PlanT i o m b #

(<$) :: a -> PlanT i o m b -> PlanT i o m a #

Applicative (PlanT i o m) Source # 

Methods

pure :: a -> PlanT i o m a #

(<*>) :: PlanT i o m (a -> b) -> PlanT i o m a -> PlanT i o m b #

liftA2 :: (a -> b -> c) -> PlanT i o m a -> PlanT i o m b -> PlanT i o m c #

(*>) :: PlanT i o m a -> PlanT i o m b -> PlanT i o m b #

(<*) :: PlanT i o m a -> PlanT i o m b -> PlanT i o m a #

MonadIO m => MonadIO (PlanT i o m) Source # 

Methods

liftIO :: IO a -> PlanT i o m a #

Monad m => Alternative (PlanT i o m) Source # 

Methods

empty :: PlanT i o m a #

(<|>) :: PlanT i o m a -> PlanT i o m a -> PlanT i o m a #

some :: PlanT i o m a -> PlanT i o m [a] #

many :: PlanT i o m a -> PlanT i o m [a] #

Monad m => MonadPlus (PlanT i o m) Source # 

Methods

mzero :: PlanT i o m a #

mplus :: PlanT i o m a -> PlanT i o m a -> PlanT i o m a #

Monad m => MonadStop (PlanT i o m) Source # 

Methods

stop :: PlanT i o m a Source #

Monad m => MonadYield (PlanT i o m) o Source # 

Methods

yield :: o -> PlanT i o m () Source #

Monad m => MonadAwait (PlanT i o m) i Source # 

Methods

await :: PlanT i o m i Source #

type Plan i o a = forall m. Monad m => PlanT i o m a Source #

class MonadAwait m a | m -> a where Source #

Minimal complete definition

await

Methods

await :: m a Source #

Instances

Monad m => MonadAwait (PlanT i o m) i Source # 

Methods

await :: PlanT i o m i Source #

(Monad m, Occasional o) => MonadAwait (Evolution (Event a) o m) a Source # 

Methods

await :: Evolution (Event a) o m a Source #

class MonadYield m a | m -> a where Source #

Minimal complete definition

yield

Methods

yield :: a -> m () Source #

Instances

Monad m => MonadYield (PlanT i o m) o Source # 

Methods

yield :: o -> PlanT i o m () Source #

Monad m => MonadYield (Evolution i (Event a) m) a Source # 

Methods

yield :: a -> Evolution i (Event a) m () Source #

class MonadStop m where Source #

Minimal complete definition

stop

Methods

stop :: m a Source #

Instances

Monad m => MonadStop (PlanT i o m) Source # 

Methods

stop :: PlanT i o m a Source #

(Monad m, Occasional o) => MonadStop (Evolution i o m) Source # 

Methods

stop :: Evolution i o m a Source #

catchP :: Monad m => PlanT i o m a -> PlanT i o m a -> PlanT i o m a Source #

Constructing machines from plans

constructT :: Monad m => PlanT i o m r -> ProcessT m (Event i) (Event o) Source #

repeatedlyT :: Monad m => PlanT i o m r -> ProcessT m (Event i) (Event o) Source #

construct :: Monad m => PlanT i o Identity r -> ProcessT m (Event i) (Event o) Source #

Evolution monad

Time-evolution monad, or generalized plan monad.

newtype Evolution i o m r Source #

A monad type represents time evolution of ProcessT

Constructors

Evolution 

Fields

Instances

Occasional o => MonadTrans (Evolution i o) Source # 

Methods

lift :: Monad m => m a -> Evolution i o m a #

Monad (Evolution i o m) Source # 

Methods

(>>=) :: Evolution i o m a -> (a -> Evolution i o m b) -> Evolution i o m b #

(>>) :: Evolution i o m a -> Evolution i o m b -> Evolution i o m b #

return :: a -> Evolution i o m a #

fail :: String -> Evolution i o m a #

Functor (Evolution i o m) Source # 

Methods

fmap :: (a -> b) -> Evolution i o m a -> Evolution i o m b #

(<$) :: a -> Evolution i o m b -> Evolution i o m a #

Applicative (Evolution i o m) Source # 

Methods

pure :: a -> Evolution i o m a #

(<*>) :: Evolution i o m (a -> b) -> Evolution i o m a -> Evolution i o m b #

liftA2 :: (a -> b -> c) -> Evolution i o m a -> Evolution i o m b -> Evolution i o m c #

(*>) :: Evolution i o m a -> Evolution i o m b -> Evolution i o m b #

(<*) :: Evolution i o m a -> Evolution i o m b -> Evolution i o m a #

(MonadIO m, Occasional o) => MonadIO (Evolution i o m) Source # 

Methods

liftIO :: IO a -> Evolution i o m a #

(Monad m, Occasional o) => MonadStop (Evolution i o m) Source # 

Methods

stop :: Evolution i o m a Source #

Monad m => MonadYield (Evolution i (Event a) m) a Source # 

Methods

yield :: a -> Evolution i (Event a) m () Source #

(Monad m, Occasional o) => MonadAwait (Evolution (Event a) o m) a Source # 

Methods

await :: Evolution (Event a) o m a Source #

packProc :: (Monad m, Occasional o) => m (ProcessT m i o) -> ProcessT m i o Source #

awaitProc :: (Monad m, Occasional o) => (a -> ProcessT m (Event a) o) -> ProcessT m (Event a) o -> ProcessT m (Event a) o Source #

yieldProc :: Monad m => a -> ProcessT m i (Event a) -> ProcessT m i (Event a) Source #

Running machines (at once)

runT :: (Monad m, Foldable f) => (c -> m ()) -> ProcessT m (Event b) (Event c) -> f b -> m () Source #

Run a machine.

runT_ :: (Monad m, Foldable f) => ProcessT m (Event a) (Event b) -> f a -> m () Source #

Run a machine discarding all results.

run :: Foldable f => ProcessT Identity (Event a) (Event b) -> f a -> [b] Source #

run_ :: (Foldable f, ArrowApply a) => ProcessA a (Event b) (Event c) -> a (f b) () Source #

Running machines (step-by-step)

stepRun Source #

Arguments

:: (Monad m, Monad m') 
=> (forall p. m p -> m' p)

Lifting function (pass id if m' ~ m)

-> (b -> m' ())

Callback on every output value.

-> (Maybe a -> m' ())

Callback on termination.

-> ProcessT m (Event a) (Event b)

The machine to run.

-> a

The argument to the machine.

-> m' (ProcessT m (Event a) (Event b)) 

Execute until an input consumed and the machine suspends.

During the execution, the machine may yield values or stops. It can be handled by two callbacks.

In some case the machine failed to consume the input value. If so, the value is passed to the termination callback.

stepYield Source #

Arguments

:: (Monad m, Monad m') 
=> (forall p. m p -> m' p)

Lifting function (pass id if m' ~ m)

-> m' a

Callback on input value request.

-> m' ()

Callback on termination

-> ProcessT m (Event a) (Event b)

The machine to run.

-> m' (Maybe b, ProcessT m (Event a) (Event b)) 

Execute until an output produced.

During the execution, the machine may await values or stops. It can be handled by two callbacks.

If the machine stops without producing any value, The first element of the return tuple is Nothing.

Primitive machines - switches

Switches inspired by the Yampa library. Signature is almost same, but collection requirement is not only Functor, but Traversable. This is because of side effects.

switch :: Monad m => ProcessT m b (c, Event t) -> (t -> ProcessT m b c) -> ProcessT m b c Source #

Run the 1st transducer at the beggining. Then switch to 2nd when Event t occurs.

>>> :{
let
    before = proc x ->
      do
        trigger <- filterEvent (== 3) -< x
        returnA -< ((*10) <$> x, trigger)
    after t = proc x -> returnA -< (*100) <$> x
 in
    run (switch before after) [1..5]
:}
[10,20,300,400,500]

dSwitch :: Monad m => ProcessT m b (c, Event t) -> (t -> ProcessT m b c) -> ProcessT m b c Source #

Delayed version of switch

>>> :{
let
    before = proc x ->
      do
        trigger <- filterEvent (== 3) -< x
        returnA -< ((*10) <$> x, trigger)
    after t = proc x -> returnA -< (*100) <$> x
 in
    run (dSwitch before after) [1..5]
:}
[10,20,30,400,500]

rSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, Event (ProcessT m b c)) c Source #

Recurring switch.

>>> :{
let pa = proc evtp ->
      do
        evx <- returnA -< fst <$> evtp
        evarr <- filterJust -< snd <$> evtp
        rSwitch (evMap (*10)) -< (evx, evarr)
    l = [(1, Nothing),
         (2, Just (arr $ fmap (*100))),
         (3, Nothing),
         (4, Just (arr $ fmap (*1000))),
         (5, Nothing)]
  in
    run pa l
:}
[10,200,300,4000,5000]

drSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, Event (ProcessT m b c)) c Source #

Delayed version of rSwitch.

>>> :{
let pa = proc evtp ->
      do
        evx <- returnA -< fst <$> evtp
        evarr <- filterJust -< snd <$> evtp
        drSwitch (evMap (*10)) -< (evx, evarr)
    l = [(1, Nothing),
         (2, Just (arr $ fmap (*100))),
         (3, Nothing),
         (4, Just (arr $ fmap (*1000))),
         (5, Nothing)]
  in
    run pa l
:}
[10,20,300,400,5000]

kSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, c) (Event t) -> (ProcessT m b c -> t -> ProcessT m b c) -> ProcessT m b c Source #

dkSwitch :: Monad m => ProcessT m b c -> ProcessT m (b, c) (Event t) -> (ProcessT m b c -> t -> ProcessT m b c) -> ProcessT m b c Source #

gSwitch :: Monad m => ProcessT m b (p, r) -> ProcessT m p q -> ProcessT m (q, r) (c, Event t) -> (ProcessT m p q -> t -> ProcessT m b c) -> ProcessT m b c Source #

dgSwitch :: Monad m => ProcessT m b (p, r) -> ProcessT m p q -> ProcessT m (q, r) (c, Event t) -> (ProcessT m p q -> t -> ProcessT m b c) -> ProcessT m b c Source #

pSwitch :: (Monad m, Traversable col) => (forall sf. b -> col sf -> col (ext, sf)) -> col (ProcessT m ext c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m ext c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c) Source #

pSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m b c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c) Source #

dpSwitch :: (Monad m, Traversable col) => (forall sf. b -> col sf -> col (ext, sf)) -> col (ProcessT m ext c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m ext c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c) Source #

dpSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, col c) (Event mng) -> (col (ProcessT m b c) -> mng -> ProcessT m b (col c)) -> ProcessT m b (col c) Source #

rpSwitch :: (Monad m, Traversable col) => (forall sf. b -> col sf -> col (ext, sf)) -> col (ProcessT m ext c) -> ProcessT m (b, Event (col (ProcessT m ext c) -> col (ProcessT m ext c))) (col c) Source #

rpSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, Event (col (ProcessT m b c) -> col (ProcessT m b c))) (col c) Source #

drpSwitch :: (Monad m, Traversable col) => (forall sf. b -> col sf -> col (ext, sf)) -> col (ProcessT m ext c) -> ProcessT m (b, Event (col (ProcessT m ext c) -> col (ProcessT m ext c))) (col c) Source #

drpSwitchB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m (b, Event (col (ProcessT m b c) -> col (ProcessT m b c))) (col c) Source #

par :: (Monad m, Traversable col) => (forall sf. b -> col sf -> col (ext, sf)) -> col (ProcessT m ext c) -> ProcessT m b (col c) Source #

parB :: (Monad m, Traversable col) => col (ProcessT m b c) -> ProcessT m b (col c) Source #

Primitive machines - other safe primitives

fit :: (Monad m, Monad m') => (forall p. m p -> m' p) -> ProcessT m b c -> ProcessT m' b c Source #

Natural transformation

fitW :: (Monad m, Monad m', Functor w) => (forall p. w p -> p) -> (forall p q. (p -> m q) -> w p -> m' q) -> ProcessT m b c -> ProcessT m' (w b) c Source #

Experimental: more general fit.

Should w be a comonad?

Primitive machines - unsafe

unsafeExhaust :: (Monad m, Foldable f) => (b -> m (f c)) -> ProcessT m b (Event c) Source #

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)