úÎ aÜ]®M      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKL The (:< :) class The coproduct of functors A 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. The fold over  values.    The  0 type class captures all the different types of ( operations that can be executed in the  monad. The 2 type contains all the primitive effects that are $ observable on the virtual machine. The 3 monad is essentially a state monad, modifying the A store. Besides returning pure values, various primitive effects A may occur, such as printing characters or failing with an error  message. The 1 function allocate a fresh location on the heap. The - function removes the data stored at a given : location. This corresponds, for instance, to emptying an MVar. The + function returns a previously unallocated . The . function kills the thread with the specified  . MThe M/ method is used to record when a thread cannot  make progress. NWhen progress is made, the N function - | ensures that any thread can be scheduled. The - function returns the data stored at a given ! heap location, if there is any. The  constant is the  of the main process. The   and ! functions are the primitive  counterparts of O  and P  in the  monad. "The "+ function overwrites a given location with  new data. #The #0 function updates the process associated with a  given . $The $4 scheduler provides a simple round-robin scheduler. %The %& scheduler will never schedule forked ; threads, always scheduling the main thread. Only use this + scheduler if your code is not concurrent. &The &/ function is the heart of this library. Given B 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. 'The ' returns the final  after executing a  computation. Beware3: this function assumes that your computation will $ succeed, without any other visible . If your computation C reads a character from the teletype, for instance, it will return  an error. (The (, function returns the effects a computation > yields, but discards the final state of the virtual machine.  !"#$%&'( ! "#$% &('    !"#$%&'()An expression of type  ) a corresponds to an IO = computation that may print to or read from stdout and stdin  respectively. AThere is a minor caveat here. I assume that stdin and stdout are B not buffered. This is not the standard behaviour in many Haskell  compilers. *The *3 function can be used to read a character from the  teletype. +The *2 function can be used to print a character to the  teletype. )*+,-.)*+,-.)*+,-.5The  IOSpec f a is merely type synonym for IO a . Once you've C tested a module, you can use these definitions to avoid having to  change your type signatures. %Note that because this definition of 5 ignores its f  argument, each of 4, 3 , etc., is simply an empty data  type. /012345543210//012345 6A 6, is a shared, mutable variable used by STM. 8An expression of type IOSpec 8 a corresponds to an Q   computation that may use 9 and returns a value of type  a.  By itself, 80 is not terribly useful. You will probably want  to use IOSpec (ForkS :+: STMS). 9The 9! function atomically executes an 7 action. :The :0 function creates a new transactional variable. ;The ;& function reads the value stored in a  transactional variable. <The <+ function overwrites the value stored in a  transactional variable. =The =5 function abandons a transaction and retries at some  later time. >The >3 function checks if its boolean argument holds. If 8 the boolean is true, it returns (); otherwise it calls =. ?The ? function takes two 7 actions stm1 and stm2 and  performs stm1. If stm1 calls = it performs stm2. If stm1  succeeds, on the other hand, stm2 is not executed. 6789:;<=>? 8976:;<=?> 6789:;<=>?@An @ is a shared, mutable variable. AAn 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, A0 is not terribly useful. You will probably want  to use IOSpec (ForkS :+: MVarS). BThe B function creates a new @ that is initially empty. CThe C) function removes the value stored in an  @ . If the @" is empty, the thread is blocked. DThe D function fills an @ with a new value. If the  @& is not empty, the thread is blocked. @ABCDA@BCD@ABCDE<A mutable variable storing a value of type a. Note that the  types stored by an E are assumed to be Typeable. FAn expression of type IOSpec IORefS a corresponds to an IO A computation that uses mutable references and returns a value of  type a. GThe G* function creates a new mutable variable. HThe H8 function reads the value stored in a mutable variable. IThe I+ function overwrites the value stored in a  mutable variable. JThe J4 function applies a function to the value stored in  and E. EFGHIJFEGHIJEFGHIJKAn expression of type IOSpec ForkS a corresponds to an Q   computation that uses L and returns a value of  type a.  By itself, K0 is not terribly useful. You will probably want  to use IOSpec (ForkS :+: MVarS) or IOSpec (ForkS :+: STMS). LThe L" function forks off a new thread. KLKLKL C  !"#$%&'()*+,-.6789:;<=>?@ABCDEFGHIJKLR   !"#$%&'()*+,-./0123456789 4:;<=>?:@ABCDEFG<HIJK;LMNO=PQR 5 6 STU IOSpec-0.2.1Test.IOSpec.TypesTest.IOSpec.VirtualMachineTest.IOSpec.TeletypeTest.IOSpec.SurrogateTest.IOSpec.STMTest.IOSpec.MVarTest.IOSpec.IORefTest.IOSpec.Forkbase System.IO Test.IOSpec:<::+:InrInlIOSpecImpurePure foldIOSpecinjectStepBlock ExecutablestepEffectFailPrintReadCharDoneVMStore SchedulerThreadIdLocData initialStoreallocemptyLoc freshThreadId finishThread lookupHeapmainTidreadChar printChar updateHeap updateSoup roundRobinsingleThreaded runIOSpec execIOSpec evalIOSpecTeletypegetCharputCharputStrputStrLngetLineSTMSIORefSMVarSForkSTVarSTM atomicallynewTVarreadTVar writeTVarretrycheckorElseMVar newEmptyMVartakeMVarputMVarIORefnewIORef readIORef writeIORef modifyIORefforkIO blockThreadresetBlockedThreads GHC.IOBaseIO