moduleFRP.Peakachu(processList,processListV,runProgram)whereimportFRP.Peakachu.Backend(Backend(..))importFRP.Peakachu.Backend.Internal(Sink(..),MainLoop(..),ParallelIO(..))importFRP.Peakachu.Program(Program(..))importControl.Concurrent.MVar.YC(writeMVar)importControl.Concurrent(forkIO,threadDelay)importControl.Concurrent.MVar(newMVar,putMVar,readMVar,takeMVar)importControl.Monad(liftM,when)importControl.Monad.Trans.List.Funcs(repeatM)importData.List.Class(List,concat,execute,scanl,takeWhile)importData.Maybe(isNothing)importPreludehiding(concat,scanl,takeWhile)-- | "Verbose" version of 'processList'.---- The program's outputs after each input are grouped togetherprocessListV::Listl=>Programab->la->l[b]processListVprogram=liftM(progVals.snd).takeWhilefst.scanlstep(True,program)wherestep(_,Program_Nothing)_=(False,Program[]Nothing)step(_,Program_(Justmore))x=(True,morex)processList::Listl=>Programab->la->lbprocessListprogram=concat.processListVprogramdoWhile::Monadm=>mBool->m()doWhile=execute.takeWhileid.repeatMrunProgram::Backendoi->Programio->IO()runProgrambackendprogram=doprogVar<-newMVarprogramresumeVar<-newMVarTruesinkVar<-newMVarNothingletconsumeOutput=doWhile$doJustsink<-readMVarsinkVarprog@(Programvalsmore)<-takeMVarprogVarcasevalsof[]->doputMVarprogVarprogwhen(isNothing(progMoreprog))$domlQuit$sinkMainLoopsinkwriteMVarresumeVarFalsereturnFalse(x:xs)->doputMVarprogVar$ProgramxsmoresinkConsumesinkxreturnTruehandleInputval=doprog@(ProgramvalsmaybeMore)<-takeMVarprogVarcasemaybeMoreofNothing->putMVarprogVarprogJustmore->doletProgrammValsmMore=morevalputMVarprogVar$Program(vals++mVals)mMoreconsumeOutputsink<-runBackendbackendhandleInputwriteMVarsinkVar(Justsink)mlInit$sinkMainLoopsink_<-forkIO$dothreadDelay300000consumeOutputcasemlRun(sinkMainLoopsink)ofNothing->doWhile$dothreadDelay200000-- 0.2 secreadMVarresumeVarJustmainloop->runParIOmainloop