-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Abstraction for things that work like IORef. -- -- A collection of type-classes generalizing the read/write/modify -- operations for stateful variables provided by things like IORef, TVar, -- &c. @package stateref @version 0.2.1.1 -- | This module defines the "MRef" abstraction, which is a set of -- type-classes for things that behave like -- Control.Concurrent.MVar.MVars. See the documentation there -- for more info. -- -- This interface may be subject to future expansion. Presently, rather -- than providing something like -- Control.Concurrent.MVar.tryTakeMVar, instances for -- "Data.StateRef.Classes.ReadRef sr m (Maybe a)" are -- provided, giving Data.StateRef.Classes.readRef the same type -- tryTakeMRef would have if it existed. There is currently nothing like -- Control.Concurrent.MVar.tryPutMVar, though. Perhaps there -- should be. Or, perhaps this is the sort of thing the weird (to me) -- signature of Data.IORef.atomicModifyIORef is for, and an -- argument for a similar signature for -- Data.StateRef.Classes.modifyStateRef or the addition of a new -- atomicModifyStateRef function. -- -- I would like to resolve these questions in version 0.3 of this -- package. module Data.MRef.Classes class (Monad m) => NewMRef sr m a | sr -> a newMRef :: (NewMRef sr m a) => a -> m sr newEmptyMRef :: (NewMRef sr m a) => m sr class (Monad m) => TakeMRef sr m a | sr -> a takeMRef :: (TakeMRef sr m a) => sr -> m a class (Monad m) => PutMRef sr m a | sr -> a putMRef :: (PutMRef sr m a) => sr -> a -> m () class (Monad m) => DefaultMRef sr m a | sr -> a, m a -> sr module Data.StateRef.Classes class (Monad m) => NewRef sr m a | sr -> a newRef :: (NewRef sr m a) => a -> m sr class (Monad m) => WriteRef sr m a | sr -> a writeRef :: (WriteRef sr m a) => sr -> a -> m () class (Monad m) => ReadRef sr m a | sr -> a readRef :: (ReadRef sr m a) => sr -> m a class (Monad m, ReadRef sr m a, WriteRef sr m a) => ModifyRef sr m a | sr -> a atomicModifyRef :: (ModifyRef sr m a) => sr -> (a -> (a, b)) -> m b modifyRef :: (ModifyRef sr m a) => sr -> (a -> a) -> m () -- | The DefaultStateRef and Data.MRef.Classes.DefaultMRef -- are used to internally constrain types that do not escape an -- expression, so that the compiler may choose an instance for the -- reference type (which it otherwise would not, and maybe not even tell -- you until you tried to use your function). For an example, see the -- source for Data.StateRef.newCounter. See also -- Data.MRef.Classes.DefaultMRef. -- -- The sole purpose for these classes' existence is as a carrier for an -- altered set of functional dependencies, which constrain the reference -- type to be uniquely determined by the monad and the contained type. class (Monad m) => DefaultStateRef sr m a | sr -> a, m a -> sr -- | This module exports no new symbols of its own. It defines several -- basic class instances for creating, reading, and writing standard -- reference types, and re-exports the types for which it defines -- instances. -- -- TODO: add millions of SPECIALIZE INSTANCE pragmas, for IO monad at a -- minimum. module Data.StateRef.Instances -- | A mutable variable in the IO monad data IORef a :: * -> * -- | An MVar (pronounced "em-var") is a synchronising variable, used -- for communication between concurrent threads. It can be thought of as -- a a box, which may be empty or full. data MVar a :: * -> * class (Monad m) => MonadIO m :: (* -> *) liftIO :: (MonadIO m) => IO a -> m a -- | a value of type STRef s a is a mutable variable in state -- thread s, containing a value of type a data STRef s a :: * -> * -> * -- | The strict state-transformer monad. A computation of type -- ST s a transforms an internal state indexed by -- s, and returns a value of type a. The s -- parameter is either -- -- -- -- It serves to keep the internal states of different invocations of -- runST separate from each other and from invocations of -- Control.Monad.ST.stToIO. -- -- The >>= and >> operations are strict in the -- state (though not in values stored in the state). For example, -- -- runST (writeSTRef _|_ v >>= f) = _|_ data ST s a :: * -> * -> * -- | RealWorld is deeply magical. It is primitive, but it -- is not unlifted (hence ptrArg). We never manipulate -- values of type RealWorld; it's only used in the type system, -- to parameterise State#. data RealWorld :: * -- | The type ForeignPtr represents references to objects that are -- maintained in a foreign language, i.e., that are not part of the data -- structures usually managed by the Haskell storage manager. The -- essential difference between ForeignPtrs and vanilla memory -- references of type Ptr a is that the former may be associated -- with finalizers. A finalizer is a routine that is invoked when -- the Haskell storage manager detects that - within the Haskell heap and -- stack - there are no more references left that are pointing to the -- ForeignPtr. Typically, the finalizer will, then, invoke -- routines in the foreign language that free the resources bound by the -- foreign object. -- -- The ForeignPtr is parameterised in the same way as Ptr. -- The type argument of ForeignPtr should normally be an instance -- of class Storable. data ForeignPtr a :: * -> * -- | A monad supporting atomic memory transactions. data STM a :: * -> * -- | Shared memory locations that support atomic memory transactions. data TVar a :: * -> * -- | A TMVar is a synchronising variable, used for communication -- between concurrent threads. It can be thought of as a box, which may -- be empty or full. data TMVar a :: * -> * -- | Perform a series of STM actions atomically. -- -- You cannot use atomically inside an unsafePerformIO or -- unsafeInterleaveIO. Any attempt to do so will result in a -- runtime error. (Reason: allowing this would effectively allow a -- transaction inside a transaction, depending on exactly when the thunk -- is evaluated.) -- -- However, see newTVarIO, which can be called inside -- unsafePerformIO, and which allows top-level TVars to be -- allocated. atomically :: STM a -> IO a -- | Wrap a state reference that supports reading and writing, and add a -- potentially thread-unsafe ModifyRef instance. newtype UnsafeModifyRef sr UnsafeModifyRef :: sr -> UnsafeModifyRef sr instance (Storable a, MonadIO m) => ModifyRef (ForeignPtr a) m a instance (Storable a, MonadIO m) => WriteRef (ForeignPtr a) m a instance (Storable a, MonadIO m) => ReadRef (ForeignPtr a) m a instance (Storable a, MonadIO m) => NewRef (ForeignPtr a) m a instance (MonadIO m) => NewRef (MVar a) m (Maybe a) instance ModifyRef (STRef s a) (ST s) a instance WriteRef (STRef s a) (ST s) a instance ReadRef (STRef s a) (ST s) a instance NewRef (STRef s a) (ST s) a instance DefaultStateRef (STRef s a) (ST s) a instance ModifyRef (STRef RealWorld a) IO a instance WriteRef (STRef RealWorld a) IO a instance ReadRef (STRef RealWorld a) IO a instance NewRef (STRef RealWorld a) IO a instance ModifyRef (STRef s a) (ST s) a instance WriteRef (STRef s a) (ST s) a instance ReadRef (STRef s a) (ST s) a instance NewRef (STRef s a) (ST s) a instance DefaultStateRef (STRef s a) (ST s) a instance (MonadIO m) => ModifyRef (IORef a) m a instance (MonadIO m) => WriteRef (IORef a) m a instance (MonadIO m) => ReadRef (IORef a) m a instance (MonadIO m) => NewRef (IORef a) m a instance DefaultStateRef (IORef a) IO a instance (MonadIO m) => ReadRef (ST RealWorld a) m a instance ReadRef (ST s a) (ST s) a instance (Monad m) => NewRef (ST s a) m a instance (MonadIO m) => ReadRef (IO a) m a instance (Monad m) => NewRef (IO a) m a module Data.Accessor newtype Getter m a Getter :: (m a) -> Getter m a newtype Setter m a Setter :: (a -> m ()) -> Setter m a newtype Accessor m a Accessor :: (Getter m a, Setter m a) -> Accessor m a instance (Monad m) => WriteRef (Accessor m a) m a instance (Monad m) => ReadRef (Accessor m a) m a instance (Monad m) => WriteRef (Setter m a) m a instance (Monad m) => ReadRef (Getter m a) m a -- | This module provides classes and instances for mutable state -- references. Various implementation exist in common usage, but no way -- (until now ;-) to define functions using state references which don't -- depend on the specific monad or reference type in use. -- -- These modules use several language extensions, including -- multi-parameter type classes and functional dependencies. module Data.StateRef -- | Create a reference and constrain its type to be the default reference -- type for the monad in which it is being created. See newRef. newDefaultRef :: (DefaultStateRef sr m a, NewRef sr m a) => a -> m sr -- | Read a reference and constrain its type to be the default reference -- type for the monad in which it is being read. See readRef. readDefaultRef :: (DefaultStateRef sr m a, ReadRef sr m a) => sr -> m a -- | Write a reference and constrain its type to be the default reference -- type for the monad in which it is being written. See writeRef writeDefaultRef :: (DefaultStateRef sr m a, WriteRef sr m a) => sr -> a -> m () -- | Modify a reference and constrain its type to be the default reference -- type for the monad in which it is being modified. See -- modifyRef. atomicModifyDefaultRef :: (DefaultStateRef sr m a, ModifyRef sr m a) => sr -> (a -> (a, b)) -> m b -- | Modify a reference and constrain its type to be the default reference -- type for the monad in which it is being modified. See -- modifyRef. modifyDefaultRef :: (DefaultStateRef sr m a, ModifyRef sr m a) => sr -> (a -> a) -> m () -- | Essentially the same concept as Control.Monad.State.gets, -- Control.Monad.State.asks, et al. Typically useful to read a -- field of a referenced ADT by passing a record selector as the second -- argument. readsRef :: (ReadRef sr m a, Monad m) => sr -> (a -> b) -> m b -- | Construct a counter - a monadic value which, each time it is -- evaluated, returns the succ of the previous value returned. newCounter :: (DefaultStateRef sr m1 a, ModifyRef sr m1 a, NewRef sr m a, Enum a) => a -> m (m1 a) -- | Create a "lapse reader" (suggestions for better terminology are more -- than welcome), a sort of a time-lapse of the variable. The first -- motivating instance for this operation was a clock in a simple -- simulation application. Given a TVar Double called -- "clock", a useful value "dT" is yielded by the expression: -- mkLapseReader clock (-) -- -- note that there's a unification ghc missed here: the fundep sr -> a -- on NewRef and DefaultStateRef should cause a and a1 to be unified, -- because of the 2 constraints: NewRef sr1 m a DefaultStateRef sr1 m1 a1 -- this isn't a "bug" because the type is still valid, but it seems like -- something ghc "ought" to do, since a and a1 are doomed to unification -- anyway. mkLapseReader :: (ReadRef sr m a, ReadRef sr m1 a, NewRef sr1 m a, DefaultStateRef sr1 m1 a1, ReadRef sr1 m1 a1, WriteRef sr1 m1 a) => sr -> (a -> a1 -> b) -> m (m1 b) -- | This module exports no new symbols of its own. It defines basic class -- instances for creating, reading, and writing MVars, and -- re-exports MVar. module Data.MRef.Instances -- | An MVar (pronounced "em-var") is a synchronising variable, used -- for communication between concurrent threads. It can be thought of as -- a a box, which may be empty or full. data MVar a :: * -> * class (Monad m) => MonadIO m :: (* -> *) liftIO :: (MonadIO m) => IO a -> m a -- | A monad supporting atomic memory transactions. data STM a :: * -> * -- | A TMVar is a synchronising variable, used for communication -- between concurrent threads. It can be thought of as a box, which may -- be empty or full. data TMVar a :: * -> * -- | Shared memory locations that support atomic memory transactions. data TVar a :: * -> * -- | Perform a series of STM actions atomically. -- -- You cannot use atomically inside an unsafePerformIO or -- unsafeInterleaveIO. Any attempt to do so will result in a -- runtime error. (Reason: allowing this would effectively allow a -- transaction inside a transaction, depending on exactly when the thunk -- is evaluated.) -- -- However, see newTVarIO, which can be called inside -- unsafePerformIO, and which allows top-level TVars to be -- allocated. atomically :: STM a -> IO a instance (MonadIO m) => PutMRef (MVar a) m a instance (MonadIO m) => TakeMRef (MVar a) m a instance (MonadIO m) => NewMRef (MVar a) m a instance DefaultMRef (MVar a) IO a module Data.MRef -- | Create a m-reference and constrain its type to be the default -- reference type for the monad in which it is being created. See -- newMRef. newDefaultMRef :: (DefaultMRef sr m a, NewMRef sr m a) => a -> m sr -- | Create an empty m-reference and constrain its type to be the default -- reference type for the monad in which it is being created. See -- newMRef. newDefaultEmptyMRef :: (DefaultMRef sr m a, NewMRef sr m a) => m sr -- | See takeMRef. takeDefaultMRef :: (DefaultMRef sr m a, TakeMRef sr m a) => sr -> m a -- | See putMRef. putDefaultMRef :: (DefaultMRef sr m a, PutMRef sr m a) => sr -> a -> m ()