úÎ!h®bxl      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijk Safe>?EST pIOSpecThe  IOSpec f a is merely type synonym for IO an. Once you've tested a module, you can use these definitions to avoid having to change your type signatures.%Note that because this definition of  ignores its f argument, each of , &, etc., is simply an empty data type.Safe;=>?STIOSpecThe (:<:) classIOSpecThe coproduct of functors IOSpecA value of type   f a is either a pure value of type a or some effect, determined by f . Crucially,   f is a monad, provided f is a functor.IOSpecThe fold over   values.    5Safe>?CSTV0¶IOSpecThe X type class captures all the different types of operations that can be executed in the ! monad.IOSpecThe U type contains all the primitive effects that are observable on the virtual machine.!IOSpecThe !¾ monad is essentially a state monad, modifying the store. Besides returning pure values, various primitive effects may occur, such as printing characters or failing with an error message.(IOSpecThe (0 function allocate a fresh location on the heap.)IOSpecThe )g function removes the data stored at a given location. This corresponds, for instance, to emptying an MVar.*IOSpecThe *+ function returns a previously unallocated $.+IOSpecThe +/ function kills the thread with the specified $.lIOSpecThe l> method is used to record when a thread cannot make progress.mIOSpecWhen progress is made, the m6 function | ensures that any thread can be scheduled.,IOSpecThe ,M function returns the data stored at a given heap location, if there is any.-IOSpecThe - constant is the $ of the main process..IOSpecThe . and /. functions are the primitive counterparts of n and o in the ! monad.0IOSpecThe 05 function overwrites a given location with new data.1IOSpecThe 17 function updates the process associated with a given $.2IOSpecThe 23 scheduler provides a simple round-robin scheduler.3IOSpecThe 3‹ scheduler will never schedule forked threads, always scheduling the main thread. Only use this scheduler if your code is not concurrent.4IOSpecThe 4w function is the heart of this library. Given the scheduling algorithm you want to use, it will run a value of type   f aN, returning the sequence of observable effects together with the final store.5IOSpecThe 5 returns the final " after executing a computation.BewareW: this function assumes that your computation will succeed, without any other visible c. If your computation reads a character from the teletype, for instance, it will return an error.6IOSpecThe 6i function returns the effects a computation yields, but discards the final state of the virtual machine.  !"#$%&'()*+,-./0123456 !&%#"$'()*+,-/.01 23465Safe<>?ST8ÜBIOSpecAn expression of type   B a corresponds to an IOL computation that may print to or read from stdout and stdin respectively.ŽThere is a minor caveat here. I assume that stdin and stdout are not buffered. This is not the standard behaviour in many Haskell compilers.CIOSpecThe C= function can be used to read a character from the teletype.DIOSpecThe C< function can be used to print a character to the teletype.BCDEFGBCDEFGSafe<>?CSTVHV JIOSpecA J+ is a shared, mutable variable used by STM.LIOSpecAn expression of type IOSpec L a corresponds to an p computation that may use M and returns a value of type a. By itself, L8 is not terribly useful. You will probably want to use IOSpec (ForkS :+: STMS).MIOSpecThe M! function atomically executes an K action.NIOSpecThe N/ function creates a new transactional variable.OIOSpecThe O> function reads the value stored in a transactional variable.PIOSpecThe PC function overwrites the value stored in a transactional variable.QIOSpecThe QA function abandons a transaction and retries at some later time.RIOSpecThe Rk function checks if its boolean argument holds. If the boolean is true, it returns (); otherwise it calls Q.SIOSpecThe S function takes two K actions stm1 and stm2 and performs stm1. If stm1 calls Q it performs stm2. If stm1 succeeds, on the other hand, stm2 is not executed. JKLMNOPQRS LMKJNOPQSRSafe1<>?STQèYIOSpecAn Y is a shared, mutable variable.ZIOSpecAn expression of type IOSpec MVarS a corresponds to an IOO computation that uses shared, mutable variables and returns a value of type a. By itself, Z8 is not terribly useful. You will probably want to use IOSpec (ForkS :+: MVarS).[IOSpecThe [ function creates a new Y that is initially empty.\IOSpecThe \* function removes the value stored in an Y . If the Y! is empty, the thread is blocked.]IOSpecThe ] function fills an Y with a new value. If the Y% is not empty, the thread is blocked.YZ[\]ZY[\]Safe<>?ST[˜`IOSpecPA mutable variable storing a value of type a. Note that the types stored by an ` are assumed to be Typeable.aIOSpecAn expression of type IOSpec IORefS a corresponds to an IOH computation that uses mutable references and returns a value of type a.bIOSpecThe b) function creates a new mutable variable.cIOSpecThe c7 function reads the value stored in a mutable variable.dIOSpecThe d= function overwrites the value stored in a mutable variable.eIOSpecThe e9 function applies a function to the value stored in and `.fIOSpecThe  instance for the a monad.`abcdea`bcdeSafe<>?CSTV`òhIOSpecAn expression of type IOSpec ForkS a corresponds to an p computation that uses i and returns a value of type a. By itself, h8 is not terribly useful. You will probably want to use IOSpec (ForkS :+: MVarS) or IOSpec (ForkS :+: STMS).iIOSpecThe i! function forks off a new thread.hihi Safe>?aPC  !"#$%&'()*+,-./0123456BCDEFGJKLMNOPQRSYZ[\]`abcdehi q      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH IJKLMNOPQ RSTUVWXYZ[\]^_`abcd efghijklmnopqIpqJrstu#IOSpec-0.3.1-JtiH6EStYdx2Vb5sC2mEV7Test.IOSpec.SurrogateTest.IOSpec.TypesTest.IOSpec.VirtualMachineTest.IOSpec.TeletypeTest.IOSpec.STMTest.IOSpec.MVarTest.IOSpec.IORefTest.IOSpec.Fork Test.IOSpec:+:TeletypeSTMSIORefSMVarSForkSIOSpec:<:InlInrPureImpure foldIOSpecinject $fMonadIOSpec$fApplicativeIOSpec$fFunctorIOSpec $fFunctor:+: $f:<:f:+: $f:<:f:+:0$f:<:ffStepBlock ExecutablestepEffectDoneReadCharPrintFailVMStore SchedulerThreadIdLocData initialStoreallocemptyLoc freshThreadId finishThread lookupHeapmainTidreadChar printChar updateHeap updateSoup roundRobinsingleThreaded runIOSpec execIOSpec evalIOSpec$fCoArbitraryThreadId$fArbitraryThreadId$fShowScheduler$fArbitraryScheduler $fEqEffect $fMonadEffect$fApplicativeEffect$fFunctorEffect$fExecutable:+: $fEqThreadId$fShowThreadIdgetCharputCharputStrputStrLngetLine$fExecutableTeletype$fFunctorTeletypeTVarSTM atomicallynewTVarreadTVar writeTVarretrycheckorElse $fMonadSTM$fApplicativeSTM $fFunctorSTM$fExecutableSTMS $fFunctorSTMSMVar newEmptyMVartakeMVarputMVar$fExecutableMVarS$fFunctorMVarSIORefnewIORef readIORef writeIORef modifyIORef$fExecutableIORefS$fFunctorIORefSforkIO$fExecutableForkS$fFunctorForkS blockThreadresetBlockedThreadsbase System.IOghc-prim GHC.TypesIO