-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A pure specification of the IO monad.
--   
--   This package consists of several modules, that give a pure
--   specification of functions in the IO monad:
--   
--   <ul>
--   <li><a>Test.IOSpec.Fork</a>: a pure specification of
--   <a>forkIO</a>.</li>
--   <li><a>Test.IOSpec.IORef</a>: a pure specification of most functions
--   that create and manipulate on <a>IORefs</a>.</li>
--   <li><a>Test.IOSpec.MVar</a>: a pure specification of most functions
--   that create and manipulate and <a>MVars</a>.</li>
--   <li><a>Test.IOSpec.STM</a>: a pure specification of <a>atomically</a>
--   and the <a>STM</a> monad.</li>
--   <li><a>Test.IOSpec.Teletype</a>: a pure specification of
--   <a>getChar</a>, <a>putChar</a>, and several related Prelude
--   functions.</li>
--   </ul>
--   
--   Besides these modules containing the specifications, there are a few
--   other important modules:
--   
--   <ul>
--   <li><a>Test.IOSpec.Types</a>: defines the <a>IOSpec</a> type and
--   several amenities.</li>
--   <li><a>Test.IOSpec.VirtualMachine</a>: defines a virtual machine on
--   which to execute pure specifications.</li>
--   <li><a>Test.IOSpec.Surrogate</a>: a drop-in replacement for the other
--   modules. Import this and recompile your code once you've finished
--   testing and debugging.</li>
--   </ul>
--   
--   There are several well-documented examples included with the source
--   distribution.
@package IOSpec
@version 0.3


-- | This module contains a few type signatures to help replace pure
--   specifications by their effectful counterparts.
module Test.IOSpec.Surrogate

-- | The <tt>IOSpec f a</tt> is merely type synonym for <tt>IO a</tt>. 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 <a>IOSpec</a> ignores its
--   <tt>f</tt> argument, each of <a>ForkS</a>, <a>MVarS</a>, etc., is
--   simply an empty data type.
type IOSpec f a = IO a
data ForkS
data MVarS
data IORefS
data STMS
data Teletype
data (:+:) f g


-- | This module contains the basic data types underlying the <a>IOSpec</a>
--   library. Most of the types and classes in this module are described in
--   <a>http://www.cs.nott.ac.uk/~wss/Publications/DataTypesALaCarte.pdf</a>.
module Test.IOSpec.Types

-- | A value of type <a>IOSpec</a> <tt>f</tt> <tt>a</tt> is either a pure
--   value of type <tt>a</tt> or some effect, determined by <tt>f</tt>.
--   Crucially, <a>IOSpec</a> <tt>f</tt> is a monad, provided <tt>f</tt> is
--   a functor.
data IOSpec f a
Pure :: a -> IOSpec f a
Impure :: (f (IOSpec f a)) -> IOSpec f a

-- | The fold over <a>IOSpec</a> values.
foldIOSpec :: Functor f => (a -> b) -> (f b -> b) -> IOSpec f a -> b

-- | The coproduct of functors
data (:+:) f g x
Inl :: (f x) -> (:+:) f g x
Inr :: (g x) -> (:+:) f g x

-- | The (:&lt;:) class
class (Functor sub, Functor sup) => (:<:) sub sup
inject :: (g :<: f) => g (IOSpec f a) -> IOSpec f a
instance GHC.Base.Functor f => GHC.Base.Functor (Test.IOSpec.Types.IOSpec f)
instance GHC.Base.Functor f => GHC.Base.Applicative (Test.IOSpec.Types.IOSpec f)
instance GHC.Base.Functor f => GHC.Base.Monad (Test.IOSpec.Types.IOSpec f)
instance (GHC.Base.Functor f, GHC.Base.Functor g) => GHC.Base.Functor (f Test.IOSpec.Types.:+: g)
instance GHC.Base.Functor f => f Test.IOSpec.Types.:<: f
instance (GHC.Base.Functor f, GHC.Base.Functor g) => f Test.IOSpec.Types.:<: (f Test.IOSpec.Types.:+: g)
instance (f Test.IOSpec.Types.:<: g, GHC.Base.Functor f, GHC.Base.Functor g, GHC.Base.Functor h) => f Test.IOSpec.Types.:<: (h Test.IOSpec.Types.:+: g)


-- | The virtual machine on which the specifications execute.
module Test.IOSpec.VirtualMachine

-- | The <a>VM</a> 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.
type VM a = StateT Store Effect a
type Data = Dynamic
type Loc = Int
data Scheduler
data Store
data ThreadId
initialStore :: Scheduler -> Store

-- | The <a>alloc</a> function allocate a fresh location on the heap.
alloc :: VM Loc

-- | The <a>emptyLoc</a> function removes the data stored at a given
--   location. This corresponds, for instance, to emptying an
--   <tt>MVar</tt>.
emptyLoc :: Loc -> VM ()

-- | The <a>freshThreadId</a> function returns a previously unallocated
--   <a>ThreadId</a>.
freshThreadId :: VM ThreadId

-- | The <a>finishThread</a> function kills the thread with the specified
--   <a>ThreadId</a>.
finishThread :: ThreadId -> VM ()

-- | The <a>lookupHeap</a> function returns the data stored at a given heap
--   location, if there is any.
lookupHeap :: Loc -> VM (Maybe Data)

-- | The <a>mainTid</a> constant is the <a>ThreadId</a> of the main
--   process.
mainTid :: ThreadId
printChar :: Char -> VM ()

-- | The <a>readChar</a> and <a>printChar</a> functions are the primitive
--   counterparts of <a>getChar</a> and <a>putChar</a> in the <a>VM</a>
--   monad.
readChar :: VM Char

-- | The <a>updateHeap</a> function overwrites a given location with new
--   data.
updateHeap :: Loc -> Data -> VM ()

-- | The <a>updateSoup</a> function updates the process associated with a
--   given <a>ThreadId</a>.
updateSoup :: Executable f => ThreadId -> IOSpec f a -> VM ()

-- | The <a>Effect</a> type contains all the primitive effects that are
--   observable on the virtual machine.
data Effect a
Done :: a -> Effect a
ReadChar :: (Char -> Effect a) -> Effect a
Print :: Char -> (Effect a) -> Effect a
Fail :: String -> Effect a

-- | The <a>roundRobin</a> scheduler provides a simple round-robin
--   scheduler.
roundRobin :: Scheduler

-- | The <a>singleThreaded</a> scheduler will never schedule forked
--   threads, always scheduling the main thread. Only use this scheduler if
--   your code is not concurrent.
singleThreaded :: Scheduler

-- | The <a>Executable</a> type class captures all the different types of
--   operations that can be executed in the <a>VM</a> monad.
class Functor f => Executable f
step :: Executable f => f a -> VM (Step a)
data Step a
Step :: a -> Step a
Block :: Step a

-- | The <a>runIOSpec</a> function is the heart of this library. Given the
--   scheduling algorithm you want to use, it will run a value of type
--   <a>IOSpec</a> <tt>f</tt> <tt>a</tt>, returning the sequence of
--   observable effects together with the final store.
runIOSpec :: Executable f => IOSpec f a -> Scheduler -> Effect (a, Store)

-- | The <a>evalIOSpec</a> function returns the effects a computation
--   yields, but discards the final state of the virtual machine.
evalIOSpec :: Executable f => IOSpec f a -> Scheduler -> Effect a

-- | The <a>execIOSpec</a> returns the final <a>Store</a> after executing a
--   computation.
--   
--   <i>Beware</i>: this function assumes that your computation will
--   succeed, without any other visible <a>Effect</a>. If your computation
--   reads a character from the teletype, for instance, it will return an
--   error.
execIOSpec :: Executable f => IOSpec f a -> Scheduler -> Store
instance GHC.Show.Show Test.IOSpec.VirtualMachine.ThreadId
instance GHC.Classes.Eq Test.IOSpec.VirtualMachine.ThreadId
instance Test.QuickCheck.Arbitrary.Arbitrary Test.IOSpec.VirtualMachine.ThreadId
instance Test.QuickCheck.Arbitrary.CoArbitrary Test.IOSpec.VirtualMachine.ThreadId
instance Test.QuickCheck.Arbitrary.Arbitrary Test.IOSpec.VirtualMachine.Scheduler
instance GHC.Show.Show Test.IOSpec.VirtualMachine.Scheduler
instance GHC.Base.Functor Test.IOSpec.VirtualMachine.Effect
instance GHC.Base.Applicative Test.IOSpec.VirtualMachine.Effect
instance GHC.Base.Monad Test.IOSpec.VirtualMachine.Effect
instance GHC.Classes.Eq a => GHC.Classes.Eq (Test.IOSpec.VirtualMachine.Effect a)
instance (Test.IOSpec.VirtualMachine.Executable f, Test.IOSpec.VirtualMachine.Executable g) => Test.IOSpec.VirtualMachine.Executable (f Test.IOSpec.Types.:+: g)


-- | A pure specification of getChar and putChar.
module Test.IOSpec.Teletype

-- | An expression of type <a>IOSpec</a> <a>Teletype</a> <tt>a</tt>
--   corresponds to an <tt>IO</tt> 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.
data Teletype a

-- | The <a>getChar</a> function can be used to read a character from the
--   teletype.
getChar :: (:<:) Teletype f => IOSpec f Char

-- | The <a>getChar</a> function can be used to print a character to the
--   teletype.
putChar :: (Teletype :<: f) => Char -> IOSpec f ()
putStr :: (Teletype :<: f) => String -> IOSpec f ()
putStrLn :: (Teletype :<: f) => String -> IOSpec f ()
getLine :: (Teletype :<: f) => IOSpec f String
instance GHC.Base.Functor Test.IOSpec.Teletype.Teletype
instance Test.IOSpec.VirtualMachine.Executable Test.IOSpec.Teletype.Teletype

module Test.IOSpec.STM

-- | An expression of type <tt>IOSpec <a>STMS</a> a</tt> corresponds to an
--   <a>IO</a> computation that may use <a>atomically</a> and returns a
--   value of type <tt>a</tt>.
--   
--   By itself, <a>STMS</a> is not terribly useful. You will probably want
--   to use <tt>IOSpec (ForkS :+: STMS)</tt>.
data STMS a

-- | The <a>atomically</a> function atomically executes an <a>STM</a>
--   action.
atomically :: (STMS :<: f) => STM a -> IOSpec f a
data STM a

-- | A <a>TVar</a> is a shared, mutable variable used by STM.
data TVar a

-- | The <a>newTVar</a> function creates a new transactional variable.
newTVar :: Typeable a => a -> STM (TVar a)

-- | The <a>readTVar</a> function reads the value stored in a transactional
--   variable.
readTVar :: Typeable a => TVar a -> STM a

-- | The <a>writeTVar</a> function overwrites the value stored in a
--   transactional variable.
writeTVar :: Typeable a => TVar a -> a -> STM ()

-- | The <a>retry</a> function abandons a transaction and retries at some
--   later time.
retry :: STM a

-- | The <a>orElse</a> function takes two <a>STM</a> actions <tt>stm1</tt>
--   and <tt>stm2</tt> and performs <tt>stm1</tt>. If <tt>stm1</tt> calls
--   <a>retry</a> it performs <tt>stm2</tt>. If <tt>stm1</tt> succeeds, on
--   the other hand, <tt>stm2</tt> is not executed.
orElse :: STM a -> STM a -> STM a

-- | The <a>check</a> function checks if its boolean argument holds. If the
--   boolean is true, it returns (); otherwise it calls <a>retry</a>.
check :: Bool -> STM ()
instance GHC.Base.Functor Test.IOSpec.STM.STMS
instance Test.IOSpec.VirtualMachine.Executable Test.IOSpec.STM.STMS
instance GHC.Base.Functor Test.IOSpec.STM.STM
instance GHC.Base.Applicative Test.IOSpec.STM.STM
instance GHC.Base.Monad Test.IOSpec.STM.STM


-- | A pure specification of mutable variables.
module Test.IOSpec.IORef

-- | An expression of type <tt>IOSpec IORefS a</tt> corresponds to an
--   <tt>IO</tt> computation that uses mutable references and returns a
--   value of type <tt>a</tt>.
data IORefS a

-- | A mutable variable storing a value of type a. Note that the types
--   stored by an <a>IORef</a> are assumed to be <tt>Typeable</tt>.
data IORef a

-- | The <a>newIORef</a> function creates a new mutable variable.
newIORef :: (Typeable a, IORefS :<: f) => a -> IOSpec f (IORef a)

-- | The <a>readIORef</a> function reads the value stored in a mutable
--   variable.
readIORef :: (Typeable a, IORefS :<: f) => IORef a -> IOSpec f a

-- | The <a>writeIORef</a> function overwrites the value stored in a
--   mutable variable.
writeIORef :: (Typeable a, IORefS :<: f) => IORef a -> a -> IOSpec f ()

-- | The <a>modifyIORef</a> function applies a function to the value stored
--   in and <a>IORef</a>.
modifyIORef :: (Typeable a, IORefS :<: f) => IORef a -> (a -> a) -> IOSpec f ()
instance GHC.Base.Functor Test.IOSpec.IORef.IORefS
instance Test.IOSpec.VirtualMachine.Executable Test.IOSpec.IORef.IORefS


-- | A pure specification of basic operations on MVars.
module Test.IOSpec.MVar

-- | An expression of type <tt>IOSpec MVarS a</tt> corresponds to an
--   <tt>IO</tt> computation that uses shared, mutable variables and
--   returns a value of type <tt>a</tt>.
--   
--   By itself, <a>MVarS</a> is not terribly useful. You will probably want
--   to use <tt>IOSpec (ForkS :+: MVarS)</tt>.
data MVarS a

-- | An <a>MVar</a> is a shared, mutable variable.
data MVar a

-- | The <a>newEmptyMVar</a> function creates a new <a>MVar</a> that is
--   initially empty.
newEmptyMVar :: (Typeable a, MVarS :<: f) => IOSpec f (MVar a)

-- | The <a>takeMVar</a> function removes the value stored in an
--   <a>MVar</a>. If the <a>MVar</a> is empty, the thread is blocked.
takeMVar :: (Typeable a, MVarS :<: f) => MVar a -> IOSpec f a

-- | The <a>putMVar</a> function fills an <a>MVar</a> with a new value. If
--   the <a>MVar</a> is not empty, the thread is blocked.
putMVar :: (Typeable a, MVarS :<: f) => MVar a -> a -> IOSpec f ()
instance GHC.Base.Functor Test.IOSpec.MVar.MVarS
instance Test.IOSpec.VirtualMachine.Executable Test.IOSpec.MVar.MVarS


-- | A pure specification of <a>forkIO</a>.
module Test.IOSpec.Fork

-- | An expression of type <tt>IOSpec ForkS a</tt> corresponds to an
--   <a>IO</a> computation that uses <a>forkIO</a> and returns a value of
--   type <tt>a</tt>.
--   
--   By itself, <a>ForkS</a> is not terribly useful. You will probably want
--   to use <tt>IOSpec (ForkS :+: MVarS)</tt> or <tt>IOSpec (ForkS :+:
--   STMS)</tt>.
data ForkS a

-- | The <a>forkIO</a> function forks off a new thread.
forkIO :: (Executable f, ForkS :<: g) => IOSpec f a -> IOSpec g ThreadId
instance GHC.Base.Functor Test.IOSpec.Fork.ForkS
instance Test.IOSpec.VirtualMachine.Executable Test.IOSpec.Fork.ForkS

module Test.IOSpec
