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

-- | Extra concurrency primitives
--   
--   The concurrent-extra package offers among other things the
--   following selection of synchronisation primitives:
--   
--   
--   
- Broadcast: Wake multiple threads by broadcasting a
--   value.
--   
- Event: Wake multiple threads by signalling an event.
--   
- Lock: Enforce exclusive access to a resource. Also known
--   as a binary semaphore or mutex. The package additionally provides an
--   alternative that works in the STM monad.
--   
- RLock: A lock which can be acquired multiple times by the
--   same thread. Also known as a reentrant mutex.
--   
- ReadWriteLock: Multiple-reader, single-writer locks. Used
--   to protect shared resources which may be concurrently read, but only
--   sequentially written.
--   
- ReadWriteVar: Concurrent read, sequential write
--   variables.
--   
--   
--   Please consult the API documentation of the individual modules for
--   more detailed information.
--   
--   This package was inspired by the concurrency libraries of Java and
--   Python.
@package concurrent-extra
@version 0.7.0.12

-- | This module provides an STM version of
--   Control.Concurrent.Lock.
--   
--   This module is intended to be imported qualified. We suggest importing
--   it like:
--   
--   
--   import           Control.Concurrent.STM.Lock         ( Lock )
--   import qualified Control.Concurrent.STM.Lock as Lock ( ... )
--   
module Control.Concurrent.STM.Lock

-- | A lock is in one of two states: "locked" or "unlocked".
data Lock

-- | Create a lock in the "unlocked" state.
new :: STM Lock

-- | Create a lock in the "locked" state.
newAcquired :: STM Lock

-- | 
--   
- When the state is "locked" acquire will retry the
--   transaction.
--   
- When the state is "unlocked" acquire will change the
--   state to "locked".
--   
acquire :: Lock -> STM ()

-- | A non-blocking acquire.
--   
--   
--   
- When the state is "unlocked" tryAcquire changes the state
--   to "locked" and returns True.
--   
- When the state is "locked" tryAcquire leaves the state
--   unchanged and returns False.
--   
tryAcquire :: Lock -> STM Bool

-- | release changes the state to "unlocked" and returns
--   immediately.
--   
--   Note that it is an error to release a lock in the "unlocked" state!
release :: Lock -> STM ()

-- | A convenience function which first acquires the lock and then performs
--   the computation. When the computation terminates, whether normally or
--   by raising an exception, the lock is released.
with :: Lock -> IO a -> IO a

-- | A non-blocking with. tryWith is a convenience function
--   which first tries to acquire the lock. If that fails, Nothing
--   is returned. If it succeeds, the computation is performed. When the
--   computation terminates, whether normally or by raising an exception,
--   the lock is released and Just the result of the computation is
--   returned.
tryWith :: Lock -> IO a -> IO (Maybe a)

-- | 
--   
- When the state is "locked", wait will retry the
--   transaction
--   
- When the state is "unlocked" wait returns
--   immediately.
--   
--   
--   wait does not alter the state of the lock.
--   
--   Note that wait is just a convenience function which can be
--   defined as:
--   
--   
--   wait l = acquire l >> release l
--   
wait :: Lock -> STM ()

-- | Determines if the lock is in the "locked" state.
--   
--   Note that this is only a snapshot of the state. By the time a program
--   reacts on its result it may already be out of date.
locked :: Lock -> STM Bool
instance GHC.Classes.Eq Control.Concurrent.STM.Lock.Lock

-- | This module provides the Lock synchronisation mechanism. It was
--   inspired by the Python and Java Lock objects and should
--   behave in a similar way. See:
--   
--   http://docs.python.org/3.1/library/threading.html#lock-objects
--   
--   and:
--   
--   
--   http://java.sun.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html
--   
--   All functions are exception safe. Throwing asynchronous
--   exceptions will not compromise the internal state of a Lock.
--   
--   This module is intended to be imported qualified. We suggest importing
--   it like:
--   
--   
--   import           Control.Concurrent.Lock         ( Lock )
--   import qualified Control.Concurrent.Lock as Lock ( ... )
--   
module Control.Concurrent.Lock

-- | A lock is in one of two states: "locked" or "unlocked".
data Lock

-- | Create a lock in the "unlocked" state.
new :: IO Lock

-- | Create a lock in the "locked" state.
newAcquired :: IO Lock

-- | Acquires the Lock. Blocks if another thread has acquired the
--   Lock.
--   
--   acquire behaves as follows:
--   
--   
--   
- When the state is "unlocked" acquire changes the state to
--   "locked".
--   
- When the state is "locked" acquire blocks until a
--   call to release in another thread wakes the calling thread.
--   Upon awakening it will change the state to "locked".
--   
--   
--   There are two further important properties of acquire:
--   
--   
--   
- acquire is single-wakeup. That is, if there are multiple
--   threads blocked on acquire and the lock is released, only one
--   thread will be woken up. The runtime guarantees that the woken thread
--   completes its acquire operation.
--   
- When multiple threads are blocked on acquire, they are
--   woken up in FIFO order. This is useful for providing fairness
--   properties of abstractions built using locks. (Note that this differs
--   from the Python implementation where the wake-up order is
--   undefined.)
--   
acquire :: Lock -> IO ()

-- | A non-blocking acquire.
--   
--   
--   
- When the state is "unlocked" tryAcquire changes the state
--   to "locked" and returns True.
--   
- When the state is "locked" tryAcquire leaves the state
--   unchanged and returns False.
--   
tryAcquire :: Lock -> IO Bool

-- | release changes the state to "unlocked" and returns
--   immediately.
--   
--   Note that it is an error to release a lock in the "unlocked" state!
--   
--   If there are any threads blocked on acquire the thread that
--   first called acquire will be woken up.
release :: Lock -> IO ()

-- | A convenience function which first acquires the lock and then performs
--   the computation. When the computation terminates, whether normally or
--   by raising an exception, the lock is released.
--   
--   Note that: with = liftA2 bracket_ acquire
--   release.
with :: Lock -> IO a -> IO a

-- | A non-blocking with. tryWith is a convenience function
--   which first tries to acquire the lock. If that fails, Nothing
--   is returned. If it succeeds, the computation is performed. When the
--   computation terminates, whether normally or by raising an exception,
--   the lock is released and Just the result of the computation is
--   returned.
tryWith :: Lock -> IO a -> IO (Maybe a)

-- | 
--   
- When the state is "locked", wait blocks until a
--   call to release in another thread changes it to
--   "unlocked".
--   
- wait is multiple-wakeup, so when multiple waiters are
--   blocked on a Lock, all of them are woken up at the same
--   time.
--   
- When the state is "unlocked" wait returns
--   immediately.
--   
--   
--   wait does not alter the state of the lock.
wait :: Lock -> IO ()

-- | Determines if the lock is in the "locked" state.
--   
--   Note that this is only a snapshot of the state. By the time a program
--   reacts on its result it may already be out of date.
locked :: Lock -> IO Bool
instance GHC.Classes.Eq Control.Concurrent.Lock.Lock

-- | Multiple-reader, single-writer locks. Used to protect shared resources
--   which may be concurrently read, but only sequentially written.
--   
--   All functions are exception safe. Throwing asynchronous
--   exceptions will not compromise the internal state of an RWLock.
--   This means it is perfectly safe to kill a thread that is blocking on,
--   for example, acquireRead.
--   
--   See also Java's version:
--   http://java.sun.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html
--   
--   This module is designed to be imported qualified. We suggest importing
--   it like:
--   
--   
--   import           Control.Concurrent.ReadWriteLock        ( RWLock )
--   import qualified Control.Concurrent.ReadWriteLock as RWL ( ... )
--   
module Control.Concurrent.ReadWriteLock

-- | Multiple-reader, single-writer lock. Is in one of three states:
--   
--   
--   
- "Free": Read or write access can be acquired without
--   blocking.
--   
- "Read": One or more threads have acquired read access. Blocks
--   write access.
--   
- "Write": A single thread has acquired write access. Blocks other
--   threads from acquiring both read and write access.
--   
data RWLock

-- | Create a new RWLock in the "free" state; either read or write
--   access can be acquired without blocking.
new :: IO RWLock

-- | Create a new RWLock in the "read" state; only read can be
--   acquired without blocking.
newAcquiredRead :: IO RWLock

-- | Create a new RWLock in the "write" state; either acquiring read
--   or write will block.
newAcquiredWrite :: IO RWLock

-- | Acquire the read lock.
--   
--   Blocks if another thread has acquired write access. If
--   acquireRead terminates without throwing an exception the
--   state of the RWLock will be "read".
--   
--   Implementation note: Throws an exception when more than (maxBound ::
--   Int) simultaneous threads acquire the read lock. But that is unlikely.
acquireRead :: RWLock -> IO ()

-- | Release the read lock.
--   
--   If the calling thread was the last one to relinquish read access the
--   state will revert to "free".
--   
--   It is an error to release read access to an RWLock which is not
--   in the "read" state.
releaseRead :: RWLock -> IO ()

-- | A convenience function wich first acquires read access and then
--   performs the computation. When the computation terminates, whether
--   normally or by raising an exception, the read lock is released.
withRead :: RWLock -> IO a -> IO a

-- | 
--   
- When the state is "write", waitRead blocks until a
--   call to releaseWrite in another thread changes the state to
--   "free".
--   
- When the state is "free" or "read" waitRead returns
--   immediately.
--   
--   
--   waitRead does not alter the state of the lock.
--   
--   Note that waitRead is just a convenience function defined as:
--   
--   
--   waitRead l = mask_ $ acquireRead l >> releaseRead l
--   
waitRead :: RWLock -> IO ()

-- | Try to acquire the read lock; non blocking.
--   
--   Like acquireRead, but doesn't block. Returns True if the
--   resulting state is "read", False otherwise.
tryAcquireRead :: RWLock -> IO Bool

-- | A non-blocking withRead. First tries to acquire the lock. If
--   that fails, Nothing is returned. If it succeeds, the
--   computation is performed. When the computation terminates, whether
--   normally or by raising an exception, the lock is released and
--   Just the result of the computation is returned.
tryWithRead :: RWLock -> IO a -> IO (Maybe a)

-- | Acquire the write lock.
--   
--   Blocks if another thread has acquired either read or write access. If
--   acquireWrite terminates without throwing an exception the
--   state of the RWLock will be "write".
acquireWrite :: RWLock -> IO ()

-- | Release the write lock.
--   
--   If releaseWrite terminates without throwing an exception the
--   state will be "free".
--   
--   It is an error to release write access to an RWLock which is
--   not in the "write" state.
releaseWrite :: RWLock -> IO ()

-- | A convenience function wich first acquires write access and then
--   performs the computation. When the computation terminates, whether
--   normally or by raising an exception, the write lock is released.
withWrite :: RWLock -> IO a -> IO a

-- | 
--   
- When the state is "write" or "read" waitWrite
--   blocks until a call to releaseWrite or
--   releaseRead in another thread changes the state to "free".
--   
- When the state is "free" waitWrite returns
--   immediately.
--   
--   
--   waitWrite does not alter the state of the lock.
--   
--   Note that waitWrite is just a convenience function defined
--   as:
--   
--   
--   waitWrite l = mask_ $ acquireWrite l >> releaseWrite l
--   
waitWrite :: RWLock -> IO ()

-- | Try to acquire the write lock; non blocking.
--   
--   Like acquireWrite, but doesn't block. Returns True if
--   the resulting state is "write", False otherwise.
tryAcquireWrite :: RWLock -> IO Bool

-- | A non-blocking withWrite. First tries to acquire the lock. If
--   that fails, Nothing is returned. If it succeeds, the
--   computation is performed. When the computation terminates, whether
--   normally or by raising an exception, the lock is released and
--   Just the result of the computation is returned.
tryWithWrite :: RWLock -> IO a -> IO (Maybe a)
instance GHC.Classes.Eq Control.Concurrent.ReadWriteLock.RWLock

-- | Concurrent read, sequential write variables. Comparable to an
--   IORef with more advanced synchronization mechanisms. The value
--   stored inside the RWVar can be read and used by multiple
--   threads at the same time. Concurrent computations inside a with
--   "block" observe the same value.
--   
--   Observing and changing the contents of an RWVar are mutually
--   exclusive. The with function will block if modify is
--   active and vice-versa. Furthermore with is fully sequential and
--   will also block on concurrent calls of modify.
--   
--   The following are guaranteed deadlocks:
--   
--   
--   
- 
modify_ v $ const $ with v
--   $ const undefined

--   
- 
with v $ const $ modify_ v
--   $ const undefined

--   
- 
modify_ v $ const $
--   modify_ v $ const undefined

--   
--   
--   All functions are exception safe. Throwing asynchronous
--   exceptions will not compromise the internal state of an RWVar.
--   This also means that threads blocking on with or modify
--   and friends can still be unblocked by throwing an asynchronous
--   exception.
--   
--   This module is designed to be imported qualified. We suggest importing
--   it like:
--   
--   
--   import           Control.Concurrent.ReadWriteVar        ( RWVar )
--   import qualified Control.Concurrent.ReadWriteVar as RWV ( ... )
--   
module Control.Concurrent.ReadWriteVar

-- | Concurrently readable and sequentially writable variable.
data RWVar a

-- | Create a new RWVar.
new :: a -> IO (RWVar a)

-- | Execute an action that operates on the contents of the RWVar.
--   
--   The action is guaranteed to have a consistent view of the stored
--   value. Any function that attempts to modify the contents will
--   block until the action is completed.
--   
--   If another thread is modifying the contents of the RWVar this
--   function will block until the other thread finishes its action.
with :: RWVar a -> (a -> IO b) -> IO b

-- | Like with but doesn't block. Returns Just the result if
--   read access could be acquired without blocking, Nothing
--   otherwise.
tryWith :: RWVar a -> (a -> IO b) -> IO (Maybe b)

-- | Modify the contents of an RWVar.
--   
--   This function needs exclusive write access to the RWVar. Only
--   one thread can modify an RWVar at the same time. All others
--   will block.
modify_ :: RWVar a -> (a -> IO a) -> IO ()

-- | Modify the contents of an RWVar and return an additional value.
--   
--   Like modify_, but allows a value to be returned (β) in addition
--   to the modified value of the RWVar.
modify :: RWVar a -> (a -> IO (a, b)) -> IO b

-- | Attempt to modify the contents of an RWVar.
--   
--   Like modify_, but doesn't block. Returns True if the
--   contents could be replaced, False otherwise.
tryModify_ :: RWVar a -> (a -> IO a) -> IO Bool

-- | Attempt to modify the contents of an RWVar and return an
--   additional value.
--   
--   Like modify, but doesn't block. Returns Just the
--   additional value if the contents could be replaced, Nothing
--   otherwise.
tryModify :: RWVar a -> (a -> IO (a, b)) -> IO (Maybe b)
instance GHC.Classes.Eq (Control.Concurrent.ReadWriteVar.RWVar a)

-- | This module provides the RLock synchronisation mechanism. It
--   was inspired by the Python RLock and Java
--   ReentrantLock objects and should behave in a similar way.
--   See:
--   
--   http://docs.python.org/3.1/library/threading.html#rlock-objects
--   
--   and:
--   
--   
--   http://java.sun.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html
--   
--   All functions are exception safe. Throwing asynchronous
--   exceptions will not compromise the internal state of an RLock.
--   
--   This module is intended to be imported qualified. We suggest importing
--   it like:
--   
--   
--   import           Control.Concurrent.RLock          ( RLock )
--   import qualified Control.Concurrent.RLock as RLock ( ... )
--   
module Control.Concurrent.RLock

-- | A reentrant lock is in one of two states: "locked" or "unlocked". When
--   the lock is in the "locked" state it has two additional properties:
--   
--   
--   
- Its owner: the thread that acquired the lock.
--   
- Its acquired count: how many times its owner acquired the
--   lock.
--   
data RLock

-- | Create a reentrant lock in the "unlocked" state.
new :: IO RLock

-- | Create a reentrant lock in the "locked" state (with the current thread
--   as owner and an acquired count of 1).
newAcquired :: IO RLock

-- | Acquires the RLock. Blocks if another thread has acquired the
--   RLock.
--   
--   acquire behaves as follows:
--   
--   
--   
- When the state is "unlocked", acquire changes the state
--   to "locked" with the current thread as owner and an acquired count of
--   1.
--   
- When the state is "locked" and the current thread owns the lock
--   acquire only increments the acquired count.
--   
- When the state is "locked" and the current thread does not own the
--   lock acquire blocks until the owner releases the lock.
--   If the thread that called acquire is woken upon release of
--   the lock it will take ownership and change the state to "locked" with
--   an acquired count of 1.
--   
--   
--   There are two further important properties of acquire:
--   
--   
--   
- acquire is single-wakeup. That is, if there are multiple
--   threads blocked on acquire, and the lock is released, only
--   one thread will be woken up. The runtime guarantees that the woken
--   thread completes its acquire operation.
--   
- When multiple threads are blocked on acquire they are
--   woken up in FIFO order. This is useful for providing fairness
--   properties of abstractions built using locks. (Note that this differs
--   from the Python implementation where the wake-up order is
--   undefined.)
--   
acquire :: RLock -> IO ()

-- | A non-blocking acquire.
--   
--   
--   
- When the state is "unlocked" tryAcquire changes the state
--   to "locked" (with the current thread as owner and an acquired count of
--   1) and returns True.
--   
- When the state is "locked" tryAcquire leaves the state
--   unchanged and returns False.
--   
tryAcquire :: RLock -> IO Bool

-- | release decrements the acquired count. When a lock is
--   released with an acquired count of 1 its state is changed to
--   "unlocked".
--   
--   Note that it is both an error to release a lock in the "unlocked"
--   state and to release a lock that is not owned by the current thread.
--   
--   If there are any threads blocked on acquire the thread that
--   first called acquire will be woken up.
release :: RLock -> IO ()

-- | A convenience function which first acquires the lock and then performs
--   the computation. When the computation terminates, whether normally or
--   by raising an exception, the lock is released.
--   
--   Note that: with = liftA2 bracket_ acquire
--   release.
with :: RLock -> IO a -> IO a

-- | A non-blocking with. tryWith is a convenience function
--   which first tries to acquire the lock. If that fails, Nothing
--   is returned. If it succeeds, the computation is performed. When the
--   computation terminates, whether normally or by raising an exception,
--   the lock is released and Just the result of the computation is
--   returned.
tryWith :: RLock -> IO a -> IO (Maybe a)

-- | 
--   
- When the state is "locked" wait blocks until a
--   call to release in another thread changes it to
--   "unlocked".
--   
- When the state is "unlocked" wait returns
--   immediately.
--   
--   
--   wait does not alter the state of the lock.
--   
--   Note that wait is just a convenience function defined as:
--   
--   
--   wait l = block $ acquire l >> release l
--   
wait :: RLock -> IO ()

-- | The state of an RLock.
--   
--   
--   
- Nothing indicates an "unlocked" state.
--   
- Just (tid, n) indicates a "locked" state where the
--   thread identified by tid acquired the lock n
--   times.
--   
type State = Maybe (ThreadId, Integer)

-- | Determine the state of the reentrant lock.
--   
--   Note that this is only a snapshot of the state. By the time a program
--   reacts on its result it may already be out of date.
state :: RLock -> IO State
instance GHC.Classes.Eq Control.Concurrent.RLock.RLock

-- | A Broadcast is a mechanism for communication between threads.
--   Multiple listeners wait until a broadcaster
--   broadcasts a value. The listeners block until the
--   value is received. When the broadcaster broadcasts a value all
--   listeners are woken.
--   
--   All functions are exception safe. Throwing asynchronous
--   exceptions will not compromise the internal state of a broadcast.
--   
--   This module is designed to be imported qualified. We suggest importing
--   it like:
--   
--   
--   import           Control.Concurrent.Broadcast              ( Broadcast )
--   import qualified Control.Concurrent.Broadcast as Broadcast ( ... )
--   
module Control.Concurrent.Broadcast

-- | A broadcast is in one of two possible states:
--   
--   
--   
- "Silent": listening to the broadcast will block
--   until a value is broadcasted.
--   
- "Broadcasting x": listening to the
--   broadcast will return the value x without blocking.
--   
data Broadcast a

-- | new creates a broadcast in the "silent" state.
new :: IO (Broadcast a)

-- | newBroadcasting x creates a broadcast in the "broadcasting
--   x" state.
newBroadcasting :: a -> IO (Broadcast a)

-- | Listen to a broadcast.
--   
--   
--   
- If the broadcast is "broadcasting x", listen
--   will return x immediately.
--   
- If the broadcast is "silent", listen will block until
--   another thread broadcasts a value to the
--   broadcast.
--   
listen :: Broadcast a -> IO a

-- | Try to listen to a broadcast; non blocking.
--   
--   
--   
- If the broadcast is "broadcasting x", tryListen
--   will return Just x immediately.
--   
- If the broadcast is "silent", tryListen returns
--   Nothing immediately.
--   
tryListen :: Broadcast a -> IO (Maybe a)

-- | Listen to a broadcast if it is available within a given amount of
--   time.
--   
--   Like listen, but with a timeout. A return value of
--   Nothing indicates a timeout occurred.
--   
--   The timeout is specified in microseconds.
--   
--   If the broadcast is "silent" and a timeout of 0 μs is specified the
--   function returns Nothing without blocking.
--   
--   Negative timeouts are treated the same as a timeout of 0 μs.
listenTimeout :: Broadcast a -> Integer -> IO (Maybe a)

-- | Broadcast a value.
--   
--   broadcast b x changes the state of the broadcast b
--   to "broadcasting x".
--   
--   If the broadcast was "silent" all threads that are
--   listening to the broadcast will be woken.
broadcast :: Broadcast a -> a -> IO ()

-- | Broadcast a value before becoming "silent".
--   
--   The state of the broadcast is changed to "silent" after all threads
--   that are listening to the broadcast are woken and
--   resume with the signalled value.
--   
--   The semantics of signal are equivalent to the following definition:
--   
--   
--   signal b x = block $ broadcast b x >> silence b
--   
signal :: Broadcast a -> a -> IO ()

-- | Set a broadcast to the "silent" state.
silence :: Broadcast a -> IO ()
instance GHC.Classes.Eq (Control.Concurrent.Broadcast.Broadcast a)

-- | An Event is a simple mechanism for communication between threads: one
--   thread signals an event and other threads wait for it.
--   
--   An event has a state which is either "set" or "cleared". This state
--   can be changed with the corresponding functions set and
--   clear. The wait function blocks until the state is
--   "set". An important property of setting an event is that all
--   threads waiting for it are woken.
--   
--   It was inspired by the Python Event object. See:
--   
--   http://docs.python.org/3.1/library/threading.html#event-objects
--   
--   This module is designed to be imported qualified. We suggest importing
--   it like:
--   
--   
--   import           Control.Concurrent.Event          ( Event )
--   import qualified Control.Concurrent.Event as Event ( ... )
--   
module Control.Concurrent.Event

-- | An event is in one of two possible states: "set" or "cleared".
data Event

-- | Create an event in the "cleared" state.
new :: IO Event

-- | Create an event in the "set" state.
newSet :: IO Event

-- | Block until the event is set.
--   
--   If the state of the event is already "set" this function will return
--   immediately. Otherwise it will block until another thread calls
--   set.
--   
--   (You can also resume a thread that is waiting for an event by throwing
--   an asynchronous exception.)
wait :: Event -> IO ()

-- | Block until the event is set or until a timer expires.
--   
--   Like wait, but with a timeout. A return value of False
--   indicates a timeout occurred.
--   
--   The timeout is specified in microseconds.
--   
--   If the event is "cleared" and a timeout of 0 μs is specified the
--   function returns False without blocking.
--   
--   Negative timeouts are treated the same as a timeout of 0 μs.
waitTimeout :: Event -> Integer -> IO Bool

-- | Returns True if the state of the event is "set" and
--   False if the state is "cleared".
--   
--   Notice that this is only a snapshot of the state. By the time a
--   program reacts on its result it may already be out of date.
isSet :: Event -> IO Bool

-- | Changes the state of the event to "set". All threads that where
--   waiting for this event are woken. Threads that wait after the
--   state is changed to "set" will not block at all.
set :: Event -> IO ()

-- | Changes the state to "cleared" after all threads that where waiting
--   for this event are woken. Threads that wait after a
--   signal will block until the event is set again.
--   
--   The semantics of signal are equivalent to the following definition:
--   
--   
--   signal e = mask $ set e >> clear e
--   
signal :: Event -> IO ()

-- | Changes the state of the event to "cleared". Threads that wait
--   after the state is changed to "cleared" will block until the state is
--   changed to "set".
clear :: Event -> IO ()
instance GHC.Classes.Eq Control.Concurrent.Event.Event
