-- |-- Module: Control.Wire.Trans.Event-- Copyright: (c) 2012 Ertugrul Soeylemez-- License: BSD3-- Maintainer: Ertugrul Soeylemez <es@ertes.de>---- Event-related wire combinators.moduleControl.Wire.Trans.Event(-- * CombinatorseitherE,(<||>),-- * Holding eventshold,hold_,holdFor,holdForI,-- * Inhibition(<!>),event,exhibit,gotEvent,notE)whereimportControl.ArrowimportControl.CategoryimportControl.Wire.TypesimportControl.Wire.WireimportData.Monoidhiding((<>))importData.SemigroupimportPreludehiding((.),id)-- | Try both wires combining their results with the given functions.---- * Like argument wires.---- * Inhibits: when both wires inhibit.eitherE::(Monadm,Monoide)=>(b1->b)-- ^ Only left.->(b2->b)-- ^ Only right.->(b1->b2->b)-- ^ Both.->Wireemab1-- ^ First wire.->Wireemab2-- ^ Second wire.->WireemabeitherEleftrightboth=eitherE'whereeitherE'w1'w2'=mkGen$\dtx'->do(mx1,w1)<-stepWirew1'dtx'(mx2,w2)<-stepWirew2'dtx'letres=case(mx1,mx2)of(Leftex1,Leftex2)->Left(mappendex1ex2)(Rightx1,Rightx2)->Right(bothx1x2)(Rightx1,_)->Right(leftx1)(_,Rightx2)->Right(rightx2)return(res,eitherE'w1w2)-- | Semigroup version of 'eitherE'.(<||>)::(Monadm,Monoide,Semigroupb)=>Wireemab->Wireemab->Wireemab(<||>)=eitherEidid(<>)-- | If the argument wire inhibits, inhibit with the given exception-- instead.---- * Depends: like argument wire.---- * Inhibits: like argument wire.(<!>)::(Monadm)=>Wireemab->e->Wireemabw<!>ex=mapOutput(either(Left.constex)Right)w-- | Prevent a wire from inhibiting. Instead produce a signal wrapped-- in 'Maybe'.---- Note: You probably shouldn't use this function.---- * Depends: like argument wire.event::(Monadm)=>Wireemab->Wireema(Maybeb)event=mapOutput(Right.either(constNothing)Just)-- | Prevent a wire from inhibiting. Instead produce the inhibition-- value.---- Note: You probably shouldn't use this function.---- * Depends: like argument wire.exhibit::(Monadm)=>Wireemab->Wireema(Eithereb)exhibit=mapOutputRight-- | Prevent a wire from inhibiting. Instead produce 'False', if the-- wire inhibited.---- Note: You probably shouldn't use this function.---- * Depends: like argument wire.gotEvent::(Monadm)=>Wireemab->WireemaBoolgotEvent=mapOutput(Right.either(constFalse)(constTrue))-- | Hold the latest event. Produces the last produced value starting-- with the given one.---- * Depends: like argument wire.hold::(Monadm)=>b->Wireemab->Wireemabholdx0w'=mkGen$\dtx'->do(mx,w)<-stepWirew'dtx'casemxofLeft_->return(Rightx0,holdx0w)Rightx->return(Rightx,holdxw)-- | Hold the event. Once the argument wire produces the produced value-- is held until the argument wire produces again.---- * Depends: like argument wire.---- * Inhibits: until the argument wire produces for the first time.hold_::(Monadm)=>Wireemab->Wireemabhold_w'=mkGen$\dtx'->do(mx,w)<-stepWirew'dtx'return(mx,either(consthold_)holdmxw)-- | Hold the event for the given amount of time. When the argument-- wire produces, the produced value is kept for the given amount of-- time. If the wire produces again while another value is kept, the-- new value takes precedence.---- * Depends: like argument wire.---- * Inhibits: as described.holdFor::(Monadm)=>Time->Wireemab->WireemabholdFort0w=hold'.exhibitwwherehold'=mkPure$\_mx->casemxofLeft_->(mx,hold')Rightx->(mx,hold''t0x)hold''t'x'=mkPure$\dtmx->lett=t'-dtincasemxofLeft_|t>0->(Rightx',hold''tx')|otherwise->(mx,hold')Rightx->(mx,hold''t0x)-- | Hold the event for the given number of instances. When the-- argument wire produces, the produced value is kept for the given-- number of instances. If the wire produces again while another value-- is kept, the new value takes precedence.---- * Depends: like argument wire.---- * Inhibits: as described.holdForI::(Monadm)=>Time->Wireemab->WireemabholdForIt0w=hold'.exhibitwwherehold'=mkPure$\_->id&&&either(consthold')(hold''t0)hold''tx'|t<=0=hold'|otherwise=mkPure$\_mx->casemxofLeft_->(Rightx',hold''(t-1)x')Rightx->(mx,hold''t0x)-- | Act like the identity wire, if the argument wire inhibits.-- Inhibit, if the argument wire produces.---- * Depends: like argument wire.---- * Inhibits: when argument wire produces.notE::(Monadm,Monoide)=>Eventema->EventemanotEw'=mkGen$\dtx'->do(mx,w)<-stepWirew'dtx'return(either(const$Rightx')(const$Leftmempty)mx,notEw)