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

-- | Add ACID guarantees to any serializable Haskell data structure.
--   
--   Use regular Haskell data structures as your database and get stronger
--   ACID guarantees than most RDBMS offer.
@package acid-state
@version 0.14.0

module Data.Acid.CRC
crc16 :: ByteString -> Word16

-- | Low-level controls for transaction-based state changes. This module
--   defines structures and tools for running state modifiers indexed
--   either by an Method or a serialized Method. This module should rarely
--   be used directly although the Method class is needed when
--   defining events manually.
--   
--   The term 'Event' is loosely used for transactions with ACID
--   guarantees. 'Method' is loosely used for state operations without ACID
--   guarantees
module Data.Acid.Core

-- | The control structure at the very center of acid-state. This module
--   provides access to a mutable state through methods. No efforts towards
--   durability, checkpointing or sharding happens at this level. Important
--   things to keep in mind in this module: * We don't distinguish between
--   updates and queries. * We allow direct access to the core state as
--   well as through events.
data Core st

-- | The basic Method class. Each Method has an indexed result type and a
--   unique tag.
class (Typeable ev, SafeCopy ev, Typeable (MethodResult ev), SafeCopy (MethodResult ev)) => Method ev where type family MethodResult ev type family MethodState ev methodTag ev = pack (showQualifiedTypeRep (typeOf ev))
methodTag :: Method ev => ev -> Tag

-- | Method container structure that hides the exact type of the method.
data MethodContainer st
Method :: (method -> State (MethodState method) (MethodResult method)) -> MethodContainer (MethodState method)
type Tagged a = (Tag, a)

-- | Construct a new Core using an initial state and a list of Methods.
mkCore :: [MethodContainer st] -> st -> IO (Core st)

-- | Mark Core as closed. Any subsequent use will throw an exception.
closeCore :: Core st -> IO ()

-- | Access the state and then mark the Core as closed. Any subsequent use
--   will throw an exception.
closeCore' :: Core st -> (st -> IO ()) -> IO ()

-- | Modify the state component. The resulting state is ensured to be in
--   WHNF.
modifyCoreState :: Core st -> (st -> IO (st, a)) -> IO a

-- | Modify the state component. The resulting state is ensured to be in
--   WHNF.
modifyCoreState_ :: Core st -> (st -> IO st) -> IO ()

-- | Access the state component.
withCoreState :: Core st -> (st -> IO a) -> IO a

-- | Find the state action that corresponds to an in-memory method.
lookupHotMethod :: Method method => MethodMap (MethodState method) -> method -> State (MethodState method) (MethodResult method)

-- | Find the state action that corresponds to a tagged and serialized
--   method.
lookupColdMethod :: Core st -> Tagged ByteString -> State st ByteString

-- | Apply an in-memory method to the state.
runHotMethod :: Method method => Core (MethodState method) -> method -> IO (MethodResult method)

-- | Execute a method as given by a type identifier and an encoded string.
--   The exact format of the encoded string depends on the type identifier.
--   Results are encoded and type tagged before they're handed back out.
--   This function is used when running events from a log-file or from
--   another server. Events that originate locally are most likely executed
--   with the faster runHotMethod.
runColdMethod :: Core st -> Tagged ByteString -> IO ByteString

-- | Collection of Methods indexed by a Tag.
type MethodMap st = Map Tag (MethodContainer st)

-- | Construct a MethodMap from a list of Methods using their
--   associated tag.
mkMethodMap :: [MethodContainer st] -> MethodMap st

module Data.Acid.Log
data FileLog object
FileLog :: LogKey object -> MVar FHandle -> TVar EntryId -> TVar ([ByteString], [IO ()]) -> [ThreadId] -> FileLog object
[logIdentifier] :: FileLog object -> LogKey object
[logCurrent] :: FileLog object -> MVar FHandle
[logNextEntryId] :: FileLog object -> TVar EntryId
[logQueue] :: FileLog object -> TVar ([ByteString], [IO ()])
[logThreads] :: FileLog object -> [ThreadId]
data LogKey object
LogKey :: FilePath -> String -> LogKey object
[logDirectory] :: LogKey object -> FilePath
[logPrefix] :: LogKey object -> String
type EntryId = Int
openFileLog :: LogKey object -> IO (FileLog object)
closeFileLog :: FileLog object -> IO ()
pushEntry :: SafeCopy object => FileLog object -> object -> IO () -> IO ()
pushAction :: FileLog object -> IO () -> IO ()
ensureLeastEntryId :: FileLog object -> EntryId -> IO ()
readEntriesFrom :: SafeCopy object => FileLog object -> EntryId -> IO [object]
rollbackTo :: SafeCopy object => LogKey object -> EntryId -> IO ()
rollbackWhile :: SafeCopy object => LogKey object -> (object -> Bool) -> IO ()
newestEntry :: SafeCopy object => LogKey object -> IO (Maybe object)
askCurrentEntryId :: FileLog object -> IO EntryId
cutFileLog :: FileLog object -> IO EntryId
archiveFileLog :: FileLog object -> EntryId -> IO ()

module Data.Acid.Abstract

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   
--   
- Atomicity State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.
--   
- Consistency No event or set of events will break
--   your data invariants.
--   
- Isolation Transactions cannot interfere with each
--   other even when issued in parallel.
--   
- Durability Successful transaction are guaranteed
--   to survive unexpected system shutdowns (both those caused by hardware
--   and software).
--   
data AcidState st
AcidState :: (forall event. (UpdateEvent event, EventState event ~ st) => event -> IO (MVar (EventResult event))) -> (Tagged ByteString -> IO (MVar ByteString)) -> (forall event. (QueryEvent event, EventState event ~ st) => event -> IO (EventResult event)) -> (Tagged ByteString -> IO ByteString) -> IO () -> IO () -> IO () -> AnyState st -> AcidState st
[_scheduleUpdate] :: AcidState st -> forall event. (UpdateEvent event, EventState event ~ st) => event -> IO (MVar (EventResult event))
[scheduleColdUpdate] :: AcidState st -> Tagged ByteString -> IO (MVar ByteString)
[_query] :: AcidState st -> forall event. (QueryEvent event, EventState event ~ st) => event -> IO (EventResult event)
[queryCold] :: AcidState st -> Tagged ByteString -> IO ByteString

-- | Take a snapshot of the state and save it to disk. Creating checkpoints
--   makes it faster to resume AcidStates and you're free to create them as
--   often or seldom as fits your needs. Transactions can run concurrently
--   with this call.
--   
--   This call will not return until the operation has succeeded.
[createCheckpoint] :: AcidState st -> IO ()

-- | Move all log files that are no longer necessary for state restoration
--   into the Archive folder in the state directory. This folder
--   can then be backed up or thrown out as you see fit. Reverting to a
--   state before the last checkpoint will not be possible if the
--   Archive folder has been thrown out.
--   
--   This method is idempotent and does not block the normal operation of
--   the AcidState.
[createArchive] :: AcidState st -> IO ()

-- | Close an AcidState and associated resources. Any subsequent usage of
--   the AcidState will throw an exception.
[closeAcidState] :: AcidState st -> IO ()
[acidSubState] :: AcidState st -> AnyState st

-- | Issue an Update event and return immediately. The event is not durable
--   before the MVar has been filled but the order of events is honored.
--   The behavior in case of exceptions is exactly the same as for
--   update.
--   
--   If EventA is scheduled before EventB, EventA will be executed
--   before EventB:
--   
--   
--   do scheduleUpdate acid EventA
--      scheduleUpdate acid EventB
--      
--   
scheduleUpdate :: UpdateEvent event => AcidState (EventState event) -> event -> IO (MVar (EventResult event))

-- | Schedule multiple Update events and wait for them to be durable, but
--   throw away their results. This is useful for importing existing
--   datasets into an AcidState.
groupUpdates :: UpdateEvent event => AcidState (EventState event) -> [event] -> IO ()

-- | Issue an Update event and wait for its result. Once this call returns,
--   you are guaranteed that the changes to the state are durable. Events
--   may be issued in parallel.
--   
--   It's a run-time error to issue events that aren't supported by the
--   AcidState.
update :: UpdateEvent event => AcidState (EventState event) -> event -> IO (EventResult event)

-- | Same as update but lifted into any monad capable of doing IO.
update' :: (UpdateEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)

-- | Issue a Query event and wait for its result. Events may be issued in
--   parallel.
query :: QueryEvent event => AcidState (EventState event) -> event -> IO (EventResult event)

-- | Same as query but lifted into any monad capable of doing IO.
query' :: (QueryEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)
mkAnyState :: Typeable sub_st => sub_st st -> AnyState st
downcast :: (Typeable sub, Typeable st) => AcidState st -> sub st

-- | AcidState container without a transaction log. Mostly used for
--   testing.
module Data.Acid.Memory

-- | Create an AcidState given an initial value.
openMemoryState :: (IsAcidic st) => st -> IO (AcidState st)

-- | AcidState container without a transaction log. Mostly used for
--   testing.
module Data.Acid.Memory.Pure
class (SafeCopy st) => IsAcidic st
acidEvents :: IsAcidic st => [Event st]

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   
--   
- Atomicity State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.
--   
- Consistency No event or set of events will break
--   your data invariants.
--   
- Isolation Transactions cannot interfere with each
--   other even when issued in parallel.
--   
- Durability Successful transaction are guaranteed
--   to survive system failure (both hardware and software).
--   
data AcidState st

-- | We distinguish between events that modify the state and those that do
--   not.
--   
--   UpdateEvents are executed in a MonadState context and have to be
--   serialized to disk before they are considered durable.
--   
--   QueryEvents are executed in a MonadReader context and obviously do not
--   have to be serialized to disk.
data Event st
UpdateEvent :: (ev -> Update (EventState ev) (EventResult ev)) -> Event (EventState ev)
QueryEvent :: (ev -> Query (EventState ev) (EventResult ev)) -> Event (EventState ev)

-- | Events return the same thing as Methods. The exact type of
--   EventResult depends on the event.
type EventResult ev = MethodResult ev
type EventState ev = MethodState ev

-- | All UpdateEvents are also Methods.
class Method ev => UpdateEvent ev

-- | All QueryEvents are also Methods.
class Method ev => QueryEvent ev

-- | Context monad for Update events.
data Update st a

-- | Context monad for Query events.
data Query st a

-- | Create an AcidState given an initial value.
openAcidState :: IsAcidic st => st -> AcidState st

-- | Issue an Update event and wait for its result. Once this call returns,
--   you are guaranteed that the changes to the state are durable. Events
--   may be issued in parallel.
--   
--   It's a run-time error to issue events that aren't supported by the
--   AcidState.
update :: UpdateEvent event => AcidState (EventState event) -> event -> (AcidState (EventState event), EventResult event)

-- | Same as update but ignoring the event result.
update_ :: UpdateEvent event => AcidState (EventState event) -> event -> AcidState (EventState event)

-- | Issue a Query event and wait for its result.
query :: QueryEvent event => AcidState (EventState event) -> event -> EventResult event

-- | Run a query in the Update Monad.
liftQuery :: Query st a -> Update st a

-- | Execute the Update monad in a pure environment.
runUpdate :: Update s r -> s -> (r, s)

-- | Execute the Query monad in a pure environment.
runQuery :: Query s r -> s -> r

-- | This module provides the ability perform update and
--   query calls from a remote process.
--   
--   On the server-side you:
--   
--   
--   
- open your AcidState normally
--   
- then use acidServer to share the state
--   
--   
--   On the client-side you:
--   
--   
--   
- use openRemoteState to connect to the remote state
--   
- use the returned AcidState like any other AcidState
--   handle
--   
--   
--   openRemoteState and acidServer communicate over an
--   unencrypted socket. If you need an encrypted connection, see
--   acid-state-tls.
--   
--   On Unix®-like systems you can use UnixSocket to create a socket
--   file for local communication between the client and server. Access can
--   be controlled by setting the permissions of the parent directory
--   containing the socket file.
--   
--   It is also possible to perform some simple authentication using
--   sharedSecretCheck and sharedSecretPerform. Keep in mind
--   that secrets will be sent in plain-text if you do not use
--   acid-state-tls. If you are using a UnixSocket
--   additional authentication may not be required, so you can use
--   skipAuthenticationCheck and skipAuthenticationPerform.
--   
--   Working with a remote AcidState is nearly identical to working
--   with a local AcidState with a few important differences.
--   
--   The connection to the remote AcidState can be lost. The client
--   will automatically attempt to reconnect every second. Because
--   query events do not affect the state, an aborted query
--   will be retried automatically after the server is reconnected.
--   
--   If the connection was lost during an update event, the event
--   will not be retried. Instead RemoteConnectionError will be
--   raised. This is because it is impossible for the client to know if the
--   aborted update completed on the server-side or not.
--   
--   When using a local AcidState, an update event in one thread
--   does not block query events taking place in other threads. With a
--   remote connection, all queries and requests are channeled over a
--   single connection. As a result, updates and queries are performed in
--   the order they are executed and do block each other. In the rare case
--   where this is an issue, you could create one remote connection per
--   thread.
--   
--   When working with local state, a query or update which returns the
--   whole state is not usually a problem due to memory sharing. The
--   update/query event basically just needs to return a pointer to the
--   data already in memory. But, when working remotely, the entire result
--   will be serialized and sent to the remote client. Hence, it is good
--   practice to create queries and updates that will only return the
--   required data.
--   
--   This module is designed to be extenible. You can easily add your own
--   authentication methods by creating a suitable pair of functions and
--   passing them to acidServer and openRemoteState.
--   
--   It is also possible to create alternative communication layers using
--   CommChannel, process, and processRemoteState.
module Data.Acid.Remote

-- | Accept connections on port and handle requests using the
--   given AcidState. This call doesn't return.
--   
--   On Unix®-like systems you can use UnixSocket to communicate
--   using a socket file. To control access, you can set the permissions of
--   the parent directory which contains the socket file.
--   
--   see also: openRemoteState and sharedSecretCheck.
acidServer :: SafeCopy st => (CommChannel -> IO Bool) -> PortID -> AcidState st -> IO ()

-- | Works the same way as acidServer, but uses pre-binded socket
--   listenSocket.
--   
--   Can be useful when fine-tuning of socket binding parameters is needed
--   (for example, listening on a particular network interface, IPv4/IPv6
--   options).
acidServer' :: SafeCopy st => (CommChannel -> IO Bool) -> Socket -> AcidState st -> IO ()

-- | Connect to an acid-state server which is sharing an AcidState.
openRemoteState :: IsAcidic st => (CommChannel -> IO ()) -> HostName -> PortID -> IO (AcidState st)

-- | skip server-side authentication checking entirely.
skipAuthenticationCheck :: CommChannel -> IO Bool

-- | skip client-side authentication entirely.
skipAuthenticationPerform :: CommChannel -> IO ()

-- | check that the client knows a shared secret.
--   
--   The function takes a Set of shared secrets. If a client knows
--   any of them, it is considered to be trusted.
--   
--   The shared secret is any ByteString of your choice.
--   
--   If you give each client a different shared secret then you can revoke
--   access individually.
--   
--   see also: sharedSecretPerform
sharedSecretCheck :: Set ByteString -> (CommChannel -> IO Bool)

-- | attempt to authenticate with the server using a shared secret.
sharedSecretPerform :: ByteString -> (CommChannel -> IO ())
data AcidRemoteException
RemoteConnectionError :: AcidRemoteException
AcidStateClosed :: AcidRemoteException
SerializeError :: String -> AcidRemoteException
AuthenticationError :: String -> AcidRemoteException

-- | CommChannel is a record containing the IO functions we need for
--   communication between the server and client.
--   
--   We abstract this out of the core processing function so that we can
--   easily add support for SSL/TLS and Unit testing.
data CommChannel
CommChannel :: (ByteString -> IO ()) -> (Int -> IO (ByteString)) -> IO () -> CommChannel
[ccPut] :: CommChannel -> ByteString -> IO ()
[ccGetSome] :: CommChannel -> Int -> IO (ByteString)
[ccClose] :: CommChannel -> IO ()

-- | Server inner-loop
--   
--   This function is generally only needed if you are adding a new
--   communication channel.
process :: SafeCopy st => CommChannel -> AcidState st -> IO ()

-- | Client inner-loop
--   
--   This function is generally only needed if you are adding a new
--   communication channel.
processRemoteState :: IsAcidic st => IO CommChannel -> IO (AcidState st)
instance GHC.Show.Show Data.Acid.Remote.AcidRemoteException
instance GHC.Classes.Eq Data.Acid.Remote.AcidRemoteException
instance GHC.Exception.Exception Data.Acid.Remote.AcidRemoteException
instance Data.Serialize.Serialize Data.Acid.Remote.Command
instance Data.Serialize.Serialize Data.Acid.Remote.Response

-- | Home of the more specialized functions.
module Data.Acid.Advanced

-- | Issue an Update event and return immediately. The event is not durable
--   before the MVar has been filled but the order of events is honored.
--   The behavior in case of exceptions is exactly the same as for
--   update.
--   
--   If EventA is scheduled before EventB, EventA will be executed
--   before EventB:
--   
--   
--   do scheduleUpdate acid EventA
--      scheduleUpdate acid EventB
--      
--   
scheduleUpdate :: UpdateEvent event => AcidState (EventState event) -> event -> IO (MVar (EventResult event))

-- | Schedule multiple Update events and wait for them to be durable, but
--   throw away their results. This is useful for importing existing
--   datasets into an AcidState.
groupUpdates :: UpdateEvent event => AcidState (EventState event) -> [event] -> IO ()

-- | Same as update but lifted into any monad capable of doing IO.
update' :: (UpdateEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)

-- | Same as query but lifted into any monad capable of doing IO.
query' :: (QueryEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)

-- | The basic Method class. Each Method has an indexed result type and a
--   unique tag.
class (Typeable ev, SafeCopy ev, Typeable (MethodResult ev), SafeCopy (MethodResult ev)) => Method ev where type family MethodResult ev type family MethodState ev methodTag ev = pack (showQualifiedTypeRep (typeOf ev))
methodTag :: Method ev => ev -> Tag
class (SafeCopy st) => IsAcidic st
acidEvents :: IsAcidic st => [Event st]

-- | We distinguish between events that modify the state and those that do
--   not.
--   
--   UpdateEvents are executed in a MonadState context and have to be
--   serialized to disk before they are considered durable.
--   
--   QueryEvents are executed in a MonadReader context and obviously do not
--   have to be serialized to disk.
data Event st
UpdateEvent :: (ev -> Update (EventState ev) (EventResult ev)) -> Event (EventState ev)
QueryEvent :: (ev -> Query (EventState ev) (EventResult ev)) -> Event (EventState ev)

-- | AcidState container using a transaction log on disk. The term 'Event'
--   is loosely used for transactions with ACID guarantees. 'Method' is
--   loosely used for state operations without ACID guarantees (see
--   Data.Acid.Core).
module Data.Acid.Local

-- | Create an AcidState given an initial value.
--   
--   This will create or resume a log found in the "state/[typeOf state]/"
--   directory.
openLocalState :: (Typeable st, IsAcidic st) => st -> IO (AcidState st)

-- | Create an AcidState given a log directory and an initial value.
--   
--   This will create or resume a log found in directory. Running
--   two AcidState's from the same directory is an error but will not
--   result in dataloss.
openLocalStateFrom :: (IsAcidic st) => FilePath -> st -> IO (AcidState st)

-- | Create an AcidState given an initial value.
--   
--   This will create or resume a log found in the "state/[typeOf state]/"
--   directory. The most recent checkpoint will be loaded immediately but
--   the AcidState will not be opened until the returned function is
--   executed.
prepareLocalState :: (Typeable st, IsAcidic st) => st -> IO (IO (AcidState st))

-- | Create an AcidState given an initial value.
--   
--   This will create or resume a log found in directory. The most
--   recent checkpoint will be loaded immediately but the AcidState will
--   not be opened until the returned function is executed.
prepareLocalStateFrom :: (IsAcidic st) => FilePath -> st -> IO (IO (AcidState st))

-- | Same as scheduleLocalUpdate but does not immediately change the
--   localCopy and return the result mvar - returns an IO action to do this
--   instead. Take care to run actions of multiple Updates in the correct
--   order as otherwise Queries will operate on outdated state.
scheduleLocalUpdate' :: UpdateEvent event => LocalState (EventState event) -> event -> MVar (EventResult event) -> IO (IO ())

-- | Same as scheduleLocalColdUpdate but does not immediately change the
--   localCopy and return the result mvar - returns an IO action to do this
--   instead. Take care to run actions of multiple Updates in the correct
--   order as otherwise Queries will operate on outdated state.
scheduleLocalColdUpdate' :: LocalState st -> Tagged ByteString -> MVar ByteString -> IO (IO ())

-- | Save a snapshot to disk and close the AcidState as a single atomic
--   action. This is useful when you want to make sure that no events are
--   saved to disk after a checkpoint.
createCheckpointAndClose :: (SafeCopy st, Typeable st) => AcidState st -> IO ()

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   
--   
- Atomicity State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.
--   
- Consistency No event or set of events will break
--   your data invariants.
--   
- Isolation Transactions cannot interfere with each
--   other even when issued in parallel.
--   
- Durability Successful transaction are guaranteed
--   to survive system failure (both hardware and software).
--   
data LocalState st
LocalState :: Core st -> IORef st -> FileLog (Tagged ByteString) -> FileLog Checkpoint -> PrefixLock -> LocalState st
[localCore] :: LocalState st -> Core st
[localCopy] :: LocalState st -> IORef st
[localEvents] :: LocalState st -> FileLog (Tagged ByteString)
[localCheckpoints] :: LocalState st -> FileLog Checkpoint
[localLock] :: LocalState st -> PrefixLock
data Checkpoint
Checkpoint :: EntryId -> ByteString -> Checkpoint
instance Data.SafeCopy.SafeCopy.SafeCopy Data.Acid.Local.Checkpoint

-- | AcidState container using a transaction log on disk.
--   
--   To see how it all fits together, have a look at these example
--   http://mirror.seize.it/acid-state/examples/.
module Data.Acid

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   
--   
- Atomicity State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.
--   
- Consistency No event or set of events will break
--   your data invariants.
--   
- Isolation Transactions cannot interfere with each
--   other even when issued in parallel.
--   
- Durability Successful transaction are guaranteed
--   to survive unexpected system shutdowns (both those caused by hardware
--   and software).
--   
data AcidState st

-- | Create an AcidState given an initial value.
--   
--   This will create or resume a log found in the "state/[typeOf state]/"
--   directory.
openLocalState :: (Typeable st, IsAcidic st) => st -> IO (AcidState st)

-- | Create an AcidState given a log directory and an initial value.
--   
--   This will create or resume a log found in directory. Running
--   two AcidState's from the same directory is an error but will not
--   result in dataloss.
openLocalStateFrom :: (IsAcidic st) => FilePath -> st -> IO (AcidState st)

-- | Close an AcidState and associated resources. Any subsequent usage of
--   the AcidState will throw an exception.
closeAcidState :: AcidState st -> IO ()

-- | Take a snapshot of the state and save it to disk. Creating checkpoints
--   makes it faster to resume AcidStates and you're free to create them as
--   often or seldom as fits your needs. Transactions can run concurrently
--   with this call.
--   
--   This call will not return until the operation has succeeded.
createCheckpoint :: AcidState st -> IO ()

-- | Move all log files that are no longer necessary for state restoration
--   into the Archive folder in the state directory. This folder
--   can then be backed up or thrown out as you see fit. Reverting to a
--   state before the last checkpoint will not be possible if the
--   Archive folder has been thrown out.
--   
--   This method is idempotent and does not block the normal operation of
--   the AcidState.
createArchive :: AcidState st -> IO ()

-- | Issue an Update event and wait for its result. Once this call returns,
--   you are guaranteed that the changes to the state are durable. Events
--   may be issued in parallel.
--   
--   It's a run-time error to issue events that aren't supported by the
--   AcidState.
update :: UpdateEvent event => AcidState (EventState event) -> event -> IO (EventResult event)

-- | Issue a Query event and wait for its result. Events may be issued in
--   parallel.
query :: QueryEvent event => AcidState (EventState event) -> event -> IO (EventResult event)

-- | Events return the same thing as Methods. The exact type of
--   EventResult depends on the event.
type EventResult ev = MethodResult ev
type EventState ev = MethodState ev

-- | All UpdateEvents are also Methods.
class Method ev => UpdateEvent ev

-- | All QueryEvents are also Methods.
class Method ev => QueryEvent ev

-- | Context monad for Update events.
data Update st a

-- | Context monad for Query events.
data Query st a
class (SafeCopy st) => IsAcidic st

-- | Create the control structures required for acid states using Template
--   Haskell.
--   
--   This code:
--   
--   
--   myUpdate :: Argument -> Update State Result
--   myUpdate arg = ...
--   
--   myQuery :: Argument -> Query State Result
--   myQuery arg = ...
--   
--   $(makeAcidic ''State ['myUpdate, 'myQuery])
--   
--   
--   will make State an instance of IsAcidic and provide
--   the following events:
--   
--   
--   data MyUpdate = MyUpdate Argument
--   data MyQuery  = MyQuery Argument
--   
makeAcidic :: Name -> [Name] -> Q [Dec]

-- | Run a query in the Update Monad.
liftQuery :: Query st a -> Update st a
