h&E      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijk  Safe-Inferred4IOSpecThe  IOSpec f a is merely type synonym for IO a. 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-InferredIOSpecThe (:<:) 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.    5 Safe-Inferred?IOSpecThe  type class captures all the different types of operations that can be executed in the ! monad.IOSpecThe  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 ) 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 , 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 4 function is the heart of this library. Given the scheduling algorithm you want to use, it will run a value of type   f a, returning the sequence of observable effects together with the final store.5IOSpecThe 5 returns the final " after executing a computation.Beware: this function assumes that your computation will succeed, without any other visible . If your computation reads a character from the teletype, for instance, it will return an error.6IOSpecThe 6 function returns the effects a computation yields, but discards the final state of the virtual machine.  !"#$%&'()*+,-./0123456 !&%#"$'()*+,-/.01 23465 Safe-InferredBIOSpecAn expression of type   B a corresponds to an IO 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.BCDEFGBCDEFG Safe-Inferred5 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 P function overwrites the value stored in a transactional variable.QIOSpecThe Q function abandons a transaction and retries at some later time.RIOSpecThe R 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 LMKJNOPQSR Safe-Inferred6YIOSpecAn Y is a shared, mutable variable.ZIOSpecAn expression of type IOSpec MVarS a corresponds to an IO 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-Inferred`IOSpecA 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 IO 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`bcde Safe-InferredhIOSpecAn 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-Inferred  !"#$%&'()*+,-./0123456BCDEFGJKLMNOPQRSYZ[\]`abcdehi       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH IJKLMNOPQ RSTUVWXYZ[\]^_`abcd efghijklmnopqIpqJrst$IOSpec-0.3.1.2-8iliJDi2an9pnkVYOSo4RTest.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