-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Unboxed references, dynamic arrays and more -- -- This array library supports: unboxed references, Monad-independent -- references, syntax sugar for mutable types, a reimplemented Arrays -- library, changes in MArray usage, and using dynamic (resizable) arrays @package ArrayRef @version 0.1.3.1 -- | Unboxed values (simple datatypes that can be stored in ByteArrays, -- i.e. raw memory buffers allocated inside the Haskell heap) -- -- Based on the idea of Oleg Kiselyov (see -- http:www.haskell.orgpipermailhaskell-cafe2004-July006400.html) module GHC.Unboxed -- | That's all we need to unify ST and IO operations! class (Monad m) => STorIO m s | m -> s mLift :: (STorIO m s) => (State# s -> (# State# s, a #)) -> m a -- | Type functions which converts universal ST or IO types to IO-specific -- ones type IOSpecific a :: (* -> *) = a RealWorld type IOSpecific2 a :: (* -> * -> *) = a RealWorld type IOSpecific3 a :: (* -> * -> * -> *) = a RealWorld -- | Immutable and mutable byte vectors data UVec a UVec :: ByteArray# -> UVec a data MUVec s a MUVec :: (MutableByteArray# s) -> MUVec s a -- | Alloc the mutable byte vector allocUnboxedBytes :: (STorIO m s, Integral bytes, Unboxed a) => bytes -> m (MUVec s a) -- | Mutable->immutable byte vector on-place conversion unsafeFreezeUnboxed :: (STorIO m s) => MUVec s a -> m (UVec a) -- | Immutable->mutable byte vector on-place conversion unsafeThawUnboxed :: (STorIO m s) => UVec a -> m (MUVec s a) -- | Mutable->immutable byte vector conversion which takes a copy of -- contents freezeUnboxed :: (STorIO m s) => MUVec s a -> Int -> m (UVec a) -- | Immutable->mutable byte vector conversion which takes a copy of -- contents thawUnboxed :: (STorIO m s) => UVec a -> Int -> m (MUVec s a) -- | Recast immutable unboxed vector castUnboxed :: UVec a -> UVec b -- | Recast mutable unboxed vector castMUnboxed :: MUVec s a -> MUVec s b fromI# :: (Integral n) => n -> Int# memcpy :: MutableByteArray# RealWorld -> ByteArray# -> Int# -> IO () -- | Unboxed is like Storable, but values are stored in byte vectors (i.e. -- inside the Haskell heap) class Unboxed value readUnboxed :: (Unboxed value, STorIO m s, Integral index) => MUVec s value -> index -> m value writeUnboxed :: (Unboxed value, STorIO m s, Integral index) => MUVec s value -> index -> value -> m () indexUnboxed :: (Unboxed value, Integral index) => UVec value -> index -> value sizeOfUnboxed :: (Unboxed value) => value -> Int instance Unboxed (StablePtr a) instance Unboxed (FunPtr a) instance Unboxed (Ptr a) instance Unboxed Double instance Unboxed Float instance Unboxed Word64 instance Unboxed Word32 instance Unboxed Word16 instance Unboxed Word8 instance Unboxed Word instance Unboxed Int64 instance Unboxed Int32 instance Unboxed Int16 instance Unboxed Int8 instance Unboxed Int instance Unboxed Char instance Unboxed Bool instance STorIO IO RealWorld instance STorIO (ST s) s instance STorIO (ST s) s -- | Immutable arrays: class, general algorithms and ShowOrdEq -- implementations module Data.ArrayBZ.Internals.IArray -- | Class of array types with immutable bounds (even if the array elements -- are mutable). class HasBounds a bounds :: (HasBounds a, Ix i) => a i e -> (i, i) -- | Class of immutable array types. -- -- An array type has the form (a i e) where a is the -- array type constructor (kind * -> * -> *), i -- is the index type (a member of the class Ix), and e is -- the element type. The IArray class is parameterised over both -- a and e, so that instances specialised to certain -- element types can be defined. class (HasBounds a) => IArray a e unsafeArray :: (IArray a e, Ix i) => (i, i) -> [(Int, e)] -> a i e unsafeAt :: (IArray a e, Ix i) => a i e -> Int -> e unsafeReplace :: (IArray a e, Ix i) => a i e -> [(Int, e)] -> a i e unsafeAccum :: (IArray a e, Ix i) => (e -> e' -> e) -> a i e -> [(Int, e')] -> a i e unsafeAccumArray :: (IArray a e, Ix i) => (e -> e' -> e) -> e -> (i, i) -> [(Int, e')] -> a i e -- | Constructs an immutable array from a pair of bounds and a list of -- initial associations. -- -- The bounds are specified as a pair of the lowest and highest bounds in -- the array respectively. For example, a one-origin vector of length 10 -- has bounds (1,10), and a one-origin 10 by 10 matrix has bounds -- ((1,1),(10,10)). -- -- An association is a pair of the form (i,x), which defines the -- value of the array at index i to be x. The array is -- undefined if any index in the list is out of bounds. If any two -- associations in the list have the same index, the value at that index -- is implementation-dependent. (In GHC, the last value specified for -- that index is used. Other implementations will also do this for -- unboxed arrays, but Haskell 98 requires that for Array the value at -- such indices is bottom.) -- -- Because the indices must be checked for these errors, array is -- strict in the bounds argument and in the indices of the association -- list. Whether array is strict or non-strict in the elements -- depends on the array type: Data.Array.Array is a non-strict array -- type, but all of the Data.Array.Unboxed.UArray arrays are strict. Thus -- in a non-strict array, recurrences such as the following are possible: -- --
--   a = array (1,100) ((1,1) : [(i, i * a!(i-1)) | i \<- [2..100]])
--   
-- -- Not every index within the bounds of the array need appear in the -- association list, but the values associated with indices that do not -- appear will be undefined. -- -- If, in any dimension, the lower bound is greater than the upper bound, -- then the array is legal, but empty. Indexing an empty array always -- gives an array-bounds error, but bounds still yields the bounds -- with which the array was constructed. array :: (IArray a e, Ix i) => (i, i) -> [(i, e)] -> a i e -- | Constructs an immutable array from a list of initial elements. The -- list gives the elements of the array in ascending order beginning with -- the lowest index. listArray :: (IArray a e, Ix i) => (i, i) -> [e] -> a i e -- | Returns the element of an immutable array at the specified index. (!) :: (IArray a e, Ix i) => a i e -> i -> e -- | Returns a list of all the valid indices in an array. indices :: (HasBounds a, Ix i) => a i e -> [i] -- | Returns a list of all the elements of an array, in the same order as -- their indices. elems :: (IArray a e, Ix i) => a i e -> [e] -- | Returns the contents of an array as a list of associations. assocs :: (IArray a e, Ix i) => a i e -> [(i, e)] -- | Constructs an immutable array from a list of associations. Unlike -- array, the same index is allowed to occur multiple times in the -- list of associations; an accumulating function is used to -- combine the values of elements with the same index. -- -- For example, given a list of values of some index type, hist produces -- a histogram of the number of occurrences of each index within a -- specified range: -- --
--   hist :: (Ix a, Num b) => (a,a) -> [a] -> Array a b
--   hist bnds is = accumArray (+) 0 bnds [(i, 1) | i\<-is, inRange bnds i]
--   
accumArray :: (IArray a e, Ix i) => (e -> e' -> e) -> e -> (i, i) -> [(i, e')] -> a i e -- | Takes an array and a list of pairs and returns an array identical to -- the left argument except that it has been updated by the associations -- in the right argument. For example, if m is a 1-origin, n by n matrix, -- then m//[((i,i), 0) | i <- [1..n]] is the same matrix, -- except with the diagonal zeroed. -- -- As with the array function, if any two associations in the list -- have the same index, the value at that index is -- implementation-dependent. (In GHC, the last value specified for that -- index is used. Other implementations will also do this for unboxed -- arrays, but Haskell 98 requires that for Array the value at such -- indices is bottom.) -- -- For most array types, this operation is O(n) where n is -- the size of the array. However, the Data.Array.Diff.DiffArray type -- provides this operation with complexity linear in the number of -- updates. (//) :: (IArray a e, Ix i) => a i e -> [(i, e)] -> a i e -- | accum f takes an array and an association list and -- accumulates pairs from the list into the array with the accumulating -- function f. Thus accumArray can be defined using -- accum: -- --
--   accumArray f z b = accum f (array b [(i, z) | i \<- range b])
--   
accum :: (IArray a e, Ix i) => (e -> e' -> e) -> a i e -> [(i, e')] -> a i e -- | Returns a new array derived from the original array by applying a -- function to each of the elements. amap :: (IArray a e', IArray a e, Ix i) => (e' -> e) -> a i e' -> a i e -- | Returns a new array derived from the original array by applying a -- function to each of the indices. ixmap :: (IArray a e, Ix i, Ix j) => (i, i) -> (i -> j) -> a j e -> a i e showsIArray :: (IArray a e, Ix i, Show i, Show e) => Int -> a i e -> ShowS eqIArray :: (IArray a e, Ix i, Eq e) => a i e -> a i e -> Bool cmpIArray :: (IArray a e, Ix i, Ord e) => a i e -> a i e -> Ordering cmpIntIArray :: (IArray a e, Ord e) => a Int e -> a Int e -> Ordering -- | Mutable arrays: class and general algorithms Freeze/Thaw: -- mutable-immutable arrays conversion module Data.ArrayBZ.Internals.MArray -- | Value used to initialize undefined array elements arrEleBottom :: a -- | Class of array types with mutable bounds class (Monad m) => HasMutableBounds a m getBounds :: (HasMutableBounds a m, Ix i) => a i e -> m (i, i) -- | Class of mutable array types. -- -- An array type has the form (a i e) where a is the -- array type constructor (kind * -> * -> *), i -- is the index type (a member of the class Ix), and e is -- the element type. -- -- The MArray class is parameterised over both a and -- e (so that instances specialised to certain element types can -- be defined, in the same way as for IArray), and also over the -- type of the monad, m, in which the mutable array will be -- manipulated. class (Monad m, HasMutableBounds a m) => MArray a e m newArray :: (MArray a e m, Ix i) => (i, i) -> e -> m (a i e) newArray_ :: (MArray a e m, Ix i) => (i, i) -> m (a i e) unsafeRead :: (MArray a e m, Ix i) => a i e -> Int -> m e unsafeWrite :: (MArray a e m, Ix i) => a i e -> Int -> e -> m () readArray :: (MArray a e m, Ix i) => a i e -> i -> m e writeArray :: (MArray a e m, Ix i) => a i e -> i -> e -> m () -- | Constructs a mutable array from a list of initial elements. The list -- gives the elements of the array in ascending order beginning with the -- lowest index. newListArray :: (MArray a e m, Ix i) => (i, i) -> [e] -> m (a i e) -- | Return a list of all the indexes of a mutable array getIndices :: (MArray a e m, Ix i) => a i e -> m [i] -- | Return a list of all the elements of a mutable array getElems :: (MArray a e m, Ix i) => a i e -> m [e] -- | Return a list of all the associations of a mutable array, in index -- order. getAssocs :: (MArray a e m, Ix i) => a i e -> m [(i, e)] -- | Constructs a new array derived from the original array by applying a -- function to each of the elements. mapArray :: (MArray a e' m, MArray a e m, Ix i) => (e' -> e) -> a i e' -> m (a i e) -- | Constructs a new array derived from the original array by applying a -- function to each of the indices. mapIndices :: (MArray a e m, Ix i, Ix j) => (i, i) -> (i -> j) -> a j e -> m (a i e) -- | Converts a mutable array (any instance of MArray) to an -- immutable array (any instance of IArray) by taking a complete -- copy of it. freeze :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e) -- | Converts an mutable array into an immutable array. The implementation -- may either simply cast the array from one type to the other without -- copying the array, or it may take a full copy of the array. -- -- Note that because the array is possibly not copied, any subsequent -- modifications made to the mutable version of the array may be shared -- with the immutable version. It is safe to use, therefore, if the -- mutable version is never modified after the freeze operation. -- -- The non-copying implementation is supported between certain pairs of -- array types only; one constraint is that the array types must have -- identical representations. In GHC, The following pairs of array types -- have a non-copying O(1) implementation of unsafeFreeze. Because -- the optimised versions are enabled by specialisations, you will need -- to compile with optimisation (-O) to get them. -- -- unsafeFreeze :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e) -- | Converts an immutable array (any instance of IArray) into a -- mutable array (any instance of MArray) by taking a complete -- copy of it. thaw :: (Ix i, IArray a e, MArray b e m) => a i e -> m (b i e) -- | Converts an immutable array into a mutable array. The implementation -- may either simply cast the array from one type to the other without -- copying the array, or it may take a full copy of the array. -- -- Note that because the array is possibly not copied, any subsequent -- modifications made to the mutable version of the array may be shared -- with the immutable version. It is only safe to use, therefore, if the -- immutable array is never referenced again in this thread, and there is -- no possibility that it can be also referenced in another thread. If -- you use an unsafeThawwriteunsafeFreeze sequence in a -- multi-threaded setting, then you must ensure that this sequence is -- atomic with respect to other threads, or a garbage collector crash may -- result (because the write may be writing to a frozen array). -- -- The non-copying implementation is supported between certain pairs of -- array types only; one constraint is that the array types must have -- identical representations. In GHC, The following pairs of array types -- have a non-copying O(1) implementation of unsafeThaw. Because -- the optimised versions are enabled by specialisations, you will need -- to compile with optimisation (-O) to get them. -- -- unsafeThaw :: (Ix i, IArray a e, MArray b e m) => a i e -> m (b i e) -- | A storable array is an IO-mutable array which stores its contents in a -- contiguous memory block living in the C heap. Elements are stored -- according to the class Storable. You can obtain the pointer to -- the array contents to manipulate elements from languages like C. -- -- It is similar to Data.ArrayBZ.IO.IOUArray but slower. Its advantage is -- that it's compatible with C. module Data.ArrayBZ.Storable -- | The array type data StorableArray i e -- | The pointer to the array contents is obtained by -- withStorableArray. The idea is similar to ForeignPtr -- (used internally here). The pointer should be used only during -- execution of the IO action retured by the function passed as -- argument to withStorableArray. withStorableArray :: StorableArray i e -> (Ptr e -> IO a) -> IO a -- | If you want to use it afterwards, ensure that you -- touchStorableArray after the last use of the pointer, so the -- array is not freed too early. touchStorableArray :: StorableArray i e -> IO () -- | Construct a StorableArray from an arbitrary ForeignPtr. -- It is the caller's responsibility to ensure that the ForeignPtr -- points to an area of memory sufficient for the specified bounds. unsafeForeignPtrToStorableArray :: ForeignPtr e -> (i, i) -> IO (StorableArray i e) instance (Storable e) => MArray StorableArray e IO instance HasMutableBounds StorableArray IO instance HasBounds StorableArray -- | An overloaded interface to mutable arrays. For array types which can -- be used with this interface, see Data.ArrayBZ.IO, -- Data.ArrayBZ.ST, and Data.ArrayBZ.Storable. module Data.ArrayBZ.MArray -- | Class of mutable array types. -- -- An array type has the form (a i e) where a is the -- array type constructor (kind * -> * -> *), i -- is the index type (a member of the class Ix), and e is -- the element type. -- -- The MArray class is parameterised over both a and -- e (so that instances specialised to certain element types can -- be defined, in the same way as for IArray), and also over the -- type of the monad, m, in which the mutable array will be -- manipulated. class (Monad m, HasMutableBounds a m) => MArray a e m newArray :: (MArray a e m, Ix i) => (i, i) -> e -> m (a i e) newArray_ :: (MArray a e m, Ix i) => (i, i) -> m (a i e) readArray :: (MArray a e m, Ix i) => a i e -> i -> m e writeArray :: (MArray a e m, Ix i) => a i e -> i -> e -> m () -- | Class of array types with immutable bounds (even if the array elements -- are mutable). class HasBounds a bounds :: (HasBounds a, Ix i) => a i e -> (i, i) -- | Class of array types with mutable bounds class (Monad m) => HasMutableBounds a m getBounds :: (HasMutableBounds a m, Ix i) => a i e -> m (i, i) -- | Constructs a mutable array from a list of initial elements. The list -- gives the elements of the array in ascending order beginning with the -- lowest index. newListArray :: (MArray a e m, Ix i) => (i, i) -> [e] -> m (a i e) -- | Constructs a new array derived from the original array by applying a -- function to each of the elements. mapArray :: (MArray a e' m, MArray a e m, Ix i) => (e' -> e) -> a i e' -> m (a i e) -- | Constructs a new array derived from the original array by applying a -- function to each of the indices. mapIndices :: (MArray a e m, Ix i, Ix j) => (i, i) -> (i -> j) -> a j e -> m (a i e) -- | Returns a list of all the valid indices in an array. indices :: (HasBounds a, Ix i) => a i e -> [i] -- | Return a list of all the indexes of a mutable array getIndices :: (MArray a e m, Ix i) => a i e -> m [i] -- | Return a list of all the elements of a mutable array getElems :: (MArray a e m, Ix i) => a i e -> m [e] -- | Return a list of all the associations of a mutable array, in index -- order. getAssocs :: (MArray a e m, Ix i) => a i e -> m [(i, e)] -- | Converts a mutable array (any instance of MArray) to an -- immutable array (any instance of IArray) by taking a complete -- copy of it. freeze :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e) -- | Converts an mutable array into an immutable array. The implementation -- may either simply cast the array from one type to the other without -- copying the array, or it may take a full copy of the array. -- -- Note that because the array is possibly not copied, any subsequent -- modifications made to the mutable version of the array may be shared -- with the immutable version. It is safe to use, therefore, if the -- mutable version is never modified after the freeze operation. -- -- The non-copying implementation is supported between certain pairs of -- array types only; one constraint is that the array types must have -- identical representations. In GHC, The following pairs of array types -- have a non-copying O(1) implementation of unsafeFreeze. Because -- the optimised versions are enabled by specialisations, you will need -- to compile with optimisation (-O) to get them. -- -- unsafeFreeze :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e) -- | Converts an immutable array (any instance of IArray) into a -- mutable array (any instance of MArray) by taking a complete -- copy of it. thaw :: (Ix i, IArray a e, MArray b e m) => a i e -> m (b i e) -- | Converts an immutable array into a mutable array. The implementation -- may either simply cast the array from one type to the other without -- copying the array, or it may take a full copy of the array. -- -- Note that because the array is possibly not copied, any subsequent -- modifications made to the mutable version of the array may be shared -- with the immutable version. It is only safe to use, therefore, if the -- immutable array is never referenced again in this thread, and there is -- no possibility that it can be also referenced in another thread. If -- you use an unsafeThawwriteunsafeFreeze sequence in a -- multi-threaded setting, then you must ensure that this sequence is -- atomic with respect to other threads, or a garbage collector crash may -- result (because the write may be writing to a frozen array). -- -- The non-copying implementation is supported between certain pairs of -- array types only; one constraint is that the array types must have -- identical representations. In GHC, The following pairs of array types -- have a non-copying O(1) implementation of unsafeThaw. Because -- the optimised versions are enabled by specialisations, you will need -- to compile with optimisation (-O) to get them. -- -- unsafeThaw :: (Ix i, IArray a e, MArray b e m) => a i e -> m (b i e) -- | Class Unboxed represents values that can be stored in unboxed -- vectors and unboxed references -- -- Based on the: Hugs.ByteArray module module Data.Unboxed -- | Immutable and mutable byte vectors data UVec a data MUVec s a -- | Additional operations on byte vectors -- -- Alloc the mutable byte vector having elems elements of required type allocUnboxed :: (STorIO m s, Integral elems, Unboxed a) => elems -> m (MUVec s a) -- | Mutable->immutable byte vector on-place conversion unsafeFreezeUnboxed :: (STorIO m s) => MUVec s a -> m (UVec a) -- | Immutable->mutable byte vector on-place conversion unsafeThawUnboxed :: (STorIO m s) => UVec a -> m (MUVec s a) -- | Mutable->immutable byte vector conversion which takes a copy of -- contents freezeUnboxed :: (STorIO m s) => MUVec s a -> Int -> m (UVec a) -- | Immutable->mutable byte vector conversion which takes a copy of -- contents thawUnboxed :: (STorIO m s) => UVec a -> Int -> m (MUVec s a) -- | Recast immutable unboxed vector castUnboxed :: UVec a -> UVec b -- | Recast mutable unboxed vector castMUnboxed :: MUVec s a -> MUVec s b -- | Unboxed is like Storable, but values are stored in byte vectors (i.e. -- inside the Haskell heap) class Unboxed value readUnboxed :: (Unboxed value, STorIO m s, Integral index) => MUVec s value -> index -> m value writeUnboxed :: (Unboxed value, STorIO m s, Integral index) => MUVec s value -> index -> value -> m () indexUnboxed :: (Unboxed value, Integral index) => UVec value -> index -> value sizeOfUnboxed :: (Unboxed value) => value -> Int -- | Class HasDefaultValue allows to declare type's default value module Data.HasDefaultValue -- | Types that has default value class HasDefaultValue a defaultValue :: (HasDefaultValue a) => a instance HasDefaultValue (StablePtr a) instance HasDefaultValue (FunPtr a) instance HasDefaultValue (Ptr a) instance HasDefaultValue Double instance HasDefaultValue Float instance HasDefaultValue Word64 instance HasDefaultValue Word32 instance HasDefaultValue Word16 instance HasDefaultValue Word8 instance HasDefaultValue Word instance HasDefaultValue Int64 instance HasDefaultValue Int32 instance HasDefaultValue Int16 instance HasDefaultValue Int8 instance HasDefaultValue Int instance HasDefaultValue Char instance HasDefaultValue Bool -- | Unification of ST and IO operations! module Control.Monad.STorIO -- | That's all we need to unify ST and IO operations! class (Monad m) => STorIO m s | m -> s mLift :: (STorIO m s) => (State# s -> (# State# s, a #)) -> m a -- | Type functions which converts universal ST or IO types to IO-specific -- ones type IOSpecific a :: (* -> *) = a RealWorld type IOSpecific2 a :: (* -> * -> *) = a RealWorld type IOSpecific3 a :: (* -> * -> * -> *) = a RealWorld -- | Unboxed arrays -- -- Based on the idea of Oleg Kiselyov (see -- http:www.haskell.orgpipermailhaskell-cafe2004-July006400.html) module Data.ArrayBZ.Internals.Unboxed -- | Unboxed mutable arrays data UnboxedMutableArray s i e UMA :: !i -> !i -> !MUVec s e -> UnboxedMutableArray s i e -- | Unboxed mutable arrays in ST monad type STUArray = UnboxedMutableArray stUArrayTc :: TyCon -- | Unboxed mutable arrays in IO monad type IOUArray = IOSpecific3 UnboxedMutableArray iOUArrayTc :: TyCon -- | Unboxed arrays data UArray i e UA :: !i -> !i -> !UVec e -> UArray i e uArrayTc :: TyCon withNewArray :: (STorIO t t2, Ix i, MArray (UnboxedMutableArray t2) e t) => (i, i) -> e -> (UnboxedMutableArray t2 i e -> t t1) -> t (UArray i e) withArrayCopy :: (Ix t, Unboxed t1, STorIO t2 s) => UArray t t1 -> (UnboxedMutableArray s t t1 -> t2 t3) -> t2 (UArray t t1) doReplace :: (Ix i, MArray a e t) => [(Int, e)] -> a i e -> t () doAccum :: (Ix i, MArray a t1 t2) => (t1 -> t -> t1) -> [(Int, t)] -> a i t1 -> t2 () freezeUA :: (STorIO t3 t, Unboxed t2, Ix t1) => UnboxedMutableArray t t1 t2 -> t3 (UArray t1 t2) thawUA :: (STorIO t2 s, Unboxed t1, Ix t) => UArray t t1 -> t2 (UnboxedMutableArray s t t1) unsafeFreezeUA :: (STorIO t3 t1) => UnboxedMutableArray t1 t t2 -> t3 (UArray t t2) unsafeThawUA :: (STorIO t2 s) => UArray t t1 -> t2 (UnboxedMutableArray s t t1) -- | Array size in bytes sizeOfUA :: (Ix i, Unboxed e) => UArray i e -> Int sizeOfUMA :: (Ix i, Unboxed e) => UnboxedMutableArray s i e -> Int -- | Freeze/thaw rules for IOUArray freezeIOUArray :: (Unboxed e, HasDefaultValue e, Ix i) => IOUArray i e -> IO (UArray i e) thawIOUArray :: (Unboxed e, HasDefaultValue e, Ix i) => UArray i e -> IO (IOUArray i e) unsafeFreezeIOUArray :: (Unboxed e, HasDefaultValue e, Ix i) => IOUArray i e -> IO (UArray i e) unsafeThawIOUArray :: (Unboxed e, HasDefaultValue e, Ix i) => UArray i e -> IO (IOUArray i e) -- | Freeze/thaw rules for STUArray freezeSTUArray :: (Unboxed e, HasDefaultValue e, Ix i) => STUArray s i e -> ST s (UArray i e) thawSTUArray :: (Unboxed e, HasDefaultValue e, Ix i) => UArray i e -> ST s (STUArray s i e) unsafeFreezeSTUArray :: (Unboxed e, HasDefaultValue e, Ix i) => STUArray s i e -> ST s (UArray i e) unsafeThawSTUArray :: (Unboxed e, HasDefaultValue e, Ix i) => UArray i e -> ST s (STUArray s i e) -- | Casts to arrays with different element type -- -- Casts an UArray with one element type into UArray with a -- different element type. All the elements of the resulting array are -- undefined (unless you know what you're doing...). Upper array bound is -- recalculated according to elements size, for example UArray (1,2) -- Word32 -> UArray (1,8) Word8 castUArray :: (Ix i, Enum i, Unboxed e, Unboxed e') => UArray i e -> UArray i e' -- | Casts an IOUArray with one element type into IOUArray -- with a different element type (upper bound is recalculated). castIOUArray :: (Ix i, Enum i, Unboxed e, Unboxed e') => IOUArray i e -> IOUArray i e' -- | Casts an STUArray with one element type into STUArray -- with a different element type (upper bound is recalculated). castSTUArray :: (Ix i, Enum i, Unboxed e, Unboxed e') => STUArray s i e -> STUArray s i e' instance (Ix i, Ord i, Ord e, Unboxed e, HasDefaultValue e) => Ord (UArray i e) instance (Ix i, Eq i, Eq e, Unboxed e, HasDefaultValue e) => Eq (UArray i e) instance (Ix i, Show i, Show e, Unboxed e, HasDefaultValue e) => Show (UArray i e) instance (Unboxed e, HasDefaultValue e) => IArray UArray e instance HasBounds UArray instance Typeable2 UArray instance Typeable2 IOUArray instance (Unboxed e) => MArray (STUArray s) e (ST s) instance Typeable3 STUArray instance (STorIO m s, Unboxed e) => MArray (UnboxedMutableArray s) e m instance (STorIO m s) => HasMutableBounds (UnboxedMutableArray s) m instance HasBounds (UnboxedMutableArray s) -- | Unboxed arrays module Data.ArrayBZ.Unboxed -- | Unboxed arrays data UArray i e -- | Unboxed mutable arrays in IO monad type IOUArray = IOSpecific3 UnboxedMutableArray -- | Unboxed mutable arrays in ST monad type STUArray = UnboxedMutableArray -- | Casts to arrays with different element type -- -- Casts an UArray with one element type into UArray with a -- different element type. All the elements of the resulting array are -- undefined (unless you know what you're doing...). Upper array bound is -- recalculated according to elements size, for example UArray (1,2) -- Word32 -> UArray (1,8) Word8 castUArray :: (Ix i, Enum i, Unboxed e, Unboxed e') => UArray i e -> UArray i e' -- | Casts an IOUArray with one element type into IOUArray -- with a different element type (upper bound is recalculated). castIOUArray :: (Ix i, Enum i, Unboxed e, Unboxed e') => IOUArray i e -> IOUArray i e' -- | Casts an STUArray with one element type into STUArray -- with a different element type (upper bound is recalculated). castSTUArray :: (Ix i, Enum i, Unboxed e, Unboxed e') => STUArray s i e -> STUArray s i e' -- | Unboxed references -- -- Based on the idea of Oleg Kiselyov (see -- http:www.haskell.orgpipermailhaskell-cafe2004-July006400.html) module Data.Ref.Unboxed -- | Unboxed references in IO monad newtype IOURef a IOURef :: (IOSpecific2 MUVec a) -> IOURef a ioURefTc :: TyCon -- | Create new unboxed reference in IO monad newIOURef :: (Unboxed a) => a -> IO (IOURef a) -- | Read current value of unboxed reference in IO monad readIOURef :: (Unboxed a) => IOURef a -> IO a -- | Change value of unboxed reference in IO monad writeIOURef :: (Unboxed a) => IOURef a -> a -> IO () -- | Modify contents of an IOURef by applying pure function to it modifyIOURef :: (Unboxed a) => IOURef a -> (a -> a) -> IO () -- | Unboxed references in ST monad newtype STURef s a STURef :: (MUVec s a) -> STURef s a stURefTc :: TyCon -- | Create new unboxed reference in ST monad newSTURef :: (Unboxed a) => a -> ST s (STURef s a) -- | Read current value of unboxed reference in ST monad readSTURef :: (Unboxed a) => STURef s a -> ST s a -- | Change value of unboxed reference in ST monad writeSTURef :: (Unboxed a) => STURef s a -> a -> ST s () -- | Modify contents of an STURef by applying pure function to it modifySTURef :: (Unboxed a) => STURef s a -> (a -> a) -> ST s () instance Typeable2 STURef instance Typeable1 IOURef -- | Mutable boxed and unboxed references in the lazy ST monad. module Data.Ref.LazyST -- | Unboxed references in ST monad data STURef s a newSTURef :: (Unboxed a) => a -> ST s (STURef s a) readSTURef :: (Unboxed a) => STURef s a -> ST s a writeSTURef :: (Unboxed a) => STURef s a -> a -> ST s () modifySTURef :: (Unboxed a) => STURef s a -> (a -> a) -> ST s () -- | Monad-independent interfaces for boxed and unboxed references module Data.Ref.Universal -- | This class allows to create new boxed reference in monad-independent -- way (suitable for writing code that will work in IO, ST and other -- monads) class (Monad m) => Ref m r | m -> r, r -> m newRef :: (Ref m r) => a -> m (r a) readRef :: (Ref m r) => r a -> m a writeRef :: (Ref m r) => r a -> a -> m () -- | Modify the contents of an Ref by applying pure function to it modifyRef :: (Ref m r) => r a -> (a -> a) -> m () -- | Modify the contents of an Ref by applying monadic computation -- to it modifyRefM :: (Ref m r) => r a -> (a -> m a) -> m () -- | This class allows to create new unboxed reference in monad-independent -- way (suitable for writing code that will work in IO, ST and other -- monads) class (Monad m) => URef m r | m -> r, r -> m newURef :: (URef m r, Unboxed a) => a -> m (r a) readURef :: (URef m r, Unboxed a) => r a -> m a writeURef :: (URef m r, Unboxed a) => r a -> a -> m () -- | Modify the contents of an URef by applying pure function to it modifyURef :: (Unboxed a, URef m r) => r a -> (a -> a) -> m () -- | Modify the contents of an URef by applying monadic computation -- to it modifyURefM :: (Unboxed a, URef m r) => r a -> (a -> m a) -> m () instance URef (ST s) (STURef s) instance URef IO IOURef instance Ref (ST s) (STRef s) instance Ref IO IORef -- | References (mutable vars) module Data.Ref -- | Vectors of boxed values module GHC.ArrBZ -- | Immutable and mutable vectors of boxed values data Vec a Vec :: (Array# a) -> Vec a data MVec s a MVec :: (MutableArray# s a) -> MVec s a -- | Alloc the mutable vector allocBoxed :: (STorIO m s, Integral elems) => elems -> a -> m (MVec s a) -- | Mutable->immutable vector on-place conversion unsafeFreezeBoxed :: (STorIO m s) => MVec s a -> m (Vec a) -- | Immutable->mutable vector on-place conversion unsafeThawBoxed :: (STorIO m s) => Vec a -> m (MVec s a) -- | Mutable->immutable vector conversion which takes a copy of contents freezeBoxed :: (STorIO m s) => MVec s a -> Int -> a -> m (Vec a) -- | Immutable->mutable vector conversion which takes a copy of contents thawBoxed :: (STorIO m s) => Vec a -> Int -> a -> m (MVec s a) fromI# :: (Integral n) => n -> Int# -- | Read the value from mutable vector at given index readBoxed :: (STorIO m s, Integral index) => MVec s value -> index -> m value -- | Write the value to mutable vector at given index writeBoxed :: (STorIO m s, Integral index) => MVec s value -> index -> value -> m () -- | Read the value from immutable vector at given index indexBoxed :: (Integral index) => Vec value -> index -> value -- | Boxed arrays module Data.ArrayBZ.Internals.Boxed -- | Boxed mutable arrays data BoxedMutableArray s i e BMA :: !i -> !i -> !MVec s e -> BoxedMutableArray s i e -- | Boxed mutable arrays in ST monad type STArray = BoxedMutableArray -- | Boxed mutable arrays in IO monad type IOArray = IOSpecific3 BoxedMutableArray -- | Boxed immutable arrays data Array i e BA :: !i -> !i -> !Vec e -> Array i e withNewArray :: (STorIO t t2, Ix i, MArray (BoxedMutableArray t2) e t) => (i, i) -> e -> (BoxedMutableArray t2 i e -> t t1) -> t (Array i e) withArrayCopy :: (Ix t, STorIO t2 s) => Array t t1 -> (BoxedMutableArray s t t1 -> t2 t3) -> t2 (Array t t1) doReplace :: (Ix i, MArray a e t) => [(Int, e)] -> a i e -> t () doAccum :: (Ix i, MArray a t1 t2) => (t1 -> t -> t1) -> [(Int, t)] -> a i t1 -> t2 () freezeBA :: (STorIO t3 t, Ix t1) => BoxedMutableArray t t1 t2 -> t3 (Array t1 t2) thawBA :: (STorIO t2 s, Ix t) => Array t t1 -> t2 (BoxedMutableArray s t t1) unsafeFreezeBA :: (STorIO t3 t1) => BoxedMutableArray t1 t t2 -> t3 (Array t t2) unsafeThawBA :: (STorIO t2 s) => Array t t1 -> t2 (BoxedMutableArray s t t1) -- | Number of array elements sizeOfBA :: (Ix a1, HasBounds a) => a a1 e -> Int -- | Freeze/thaw rules for IOArray freezeIOArray :: (Ix i) => IOArray i e -> IO (Array i e) thawIOArray :: (Ix i) => Array i e -> IO (IOArray i e) unsafeFreezeIOArray :: (Ix i) => IOArray i e -> IO (Array i e) unsafeThawIOArray :: (Ix i) => Array i e -> IO (IOArray i e) -- | Freeze/thaw rules for STArray freezeSTArray :: (Ix i) => STArray s i e -> ST s (Array i e) thawSTArray :: (Ix i) => Array i e -> ST s (STArray s i e) unsafeFreezeSTArray :: (Ix i) => STArray s i e -> ST s (Array i e) unsafeThawSTArray :: (Ix i) => Array i e -> ST s (STArray s i e) iOArrayTc :: TyCon stArrayTc :: TyCon instance Typeable3 STArray instance Typeable2 IOArray instance (Ix i, Ord i, Ord e) => Ord (Array i e) instance (Ix i, Eq i, Eq e) => Eq (Array i e) instance (Ix i, Show i, Show e) => Show (Array i e) instance IArray Array e instance HasBounds Array instance MArray (STArray s) e (ST s) instance (STorIO m s) => MArray (BoxedMutableArray s) e m instance (STorIO m s) => HasMutableBounds (BoxedMutableArray s) m instance HasBounds (BoxedMutableArray s) -- | Boxed arrays module Data.ArrayBZ.Boxed -- | Boxed immutable arrays data Array i e -- | Boxed mutable arrays in IO monad type IOArray = IOSpecific3 BoxedMutableArray -- | Boxed mutable arrays in ST monad type STArray = BoxedMutableArray -- | Functional arrays with constant-time update. module Data.ArrayBZ.Diff -- | An arbitrary MArray type living in the IO monad can be -- converted to a diff array. data IOToDiffArray a i e -- | Fully polymorphic lazy boxed diff array. type DiffArray = IOToDiffArray IOArray -- | Strict unboxed diff array, working only for elements of primitive -- types but more compact and usually faster than DiffArray. type DiffUArray = IOToDiffArray IOUArray newDiffArray :: (MArray a e IO, Ix i) => (i, i) -> [(Int, e)] -> IO (IOToDiffArray a i e) readDiffArray :: (MArray a e IO, Ix i) => IOToDiffArray a i e -> Int -> IO e replaceDiffArray :: (MArray a e IO, Ix i) => IOToDiffArray a i e -> [(Int, e)] -> IO (IOToDiffArray a i e) instance (Ix i, Ord i, Ord e, Unboxed e, HasDefaultValue e) => Ord (DiffUArray i e) instance (Ix i, Eq i, Eq e, Unboxed e, HasDefaultValue e) => Eq (DiffUArray i e) instance (Ix i, Ord i, Ord e) => Ord (DiffArray i e) instance (Ix i, Eq i, Eq e) => Eq (DiffArray i e) instance (Ix i, Show i, Show e, Unboxed e, HasDefaultValue e) => Show (DiffUArray i e) instance (Ix i, Show i, Show e) => Show (DiffArray i e) instance (Unboxed e) => IArray DiffUArray e instance IArray DiffArray e instance (HasBounds a) => HasBounds (IOToDiffArray a) -- | Immutable arrays, with an overloaded interface. For array types which -- can be used with this interface, see the Array type exported by -- this module, and the Data.ArrayBZ.Unboxed and -- Data.ArrayBZ.Diff modules. module Data.ArrayBZ.IArray -- | Class of array types with immutable bounds (even if the array elements -- are mutable). class HasBounds a bounds :: (HasBounds a, Ix i) => a i e -> (i, i) -- | Class of immutable array types. -- -- An array type has the form (a i e) where a is the -- array type constructor (kind * -> * -> *), i -- is the index type (a member of the class Ix), and e is -- the element type. The IArray class is parameterised over both -- a and e, so that instances specialised to certain -- element types can be defined. class (HasBounds a) => IArray a e -- | Boxed immutable arrays data Array i e -- | Constructs an immutable array from a pair of bounds and a list of -- initial associations. -- -- The bounds are specified as a pair of the lowest and highest bounds in -- the array respectively. For example, a one-origin vector of length 10 -- has bounds (1,10), and a one-origin 10 by 10 matrix has bounds -- ((1,1),(10,10)). -- -- An association is a pair of the form (i,x), which defines the -- value of the array at index i to be x. The array is -- undefined if any index in the list is out of bounds. If any two -- associations in the list have the same index, the value at that index -- is implementation-dependent. (In GHC, the last value specified for -- that index is used. Other implementations will also do this for -- unboxed arrays, but Haskell 98 requires that for Array the value at -- such indices is bottom.) -- -- Because the indices must be checked for these errors, array is -- strict in the bounds argument and in the indices of the association -- list. Whether array is strict or non-strict in the elements -- depends on the array type: Data.Array.Array is a non-strict array -- type, but all of the Data.Array.Unboxed.UArray arrays are strict. Thus -- in a non-strict array, recurrences such as the following are possible: -- --
--   a = array (1,100) ((1,1) : [(i, i * a!(i-1)) | i \<- [2..100]])
--   
-- -- Not every index within the bounds of the array need appear in the -- association list, but the values associated with indices that do not -- appear will be undefined. -- -- If, in any dimension, the lower bound is greater than the upper bound, -- then the array is legal, but empty. Indexing an empty array always -- gives an array-bounds error, but bounds still yields the bounds -- with which the array was constructed. array :: (IArray a e, Ix i) => (i, i) -> [(i, e)] -> a i e -- | Constructs an immutable array from a list of initial elements. The -- list gives the elements of the array in ascending order beginning with -- the lowest index. listArray :: (IArray a e, Ix i) => (i, i) -> [e] -> a i e -- | Constructs an immutable array from a list of associations. Unlike -- array, the same index is allowed to occur multiple times in the -- list of associations; an accumulating function is used to -- combine the values of elements with the same index. -- -- For example, given a list of values of some index type, hist produces -- a histogram of the number of occurrences of each index within a -- specified range: -- --
--   hist :: (Ix a, Num b) => (a,a) -> [a] -> Array a b
--   hist bnds is = accumArray (+) 0 bnds [(i, 1) | i\<-is, inRange bnds i]
--   
accumArray :: (IArray a e, Ix i) => (e -> e' -> e) -> e -> (i, i) -> [(i, e')] -> a i e -- | Returns the element of an immutable array at the specified index. (!) :: (IArray a e, Ix i) => a i e -> i -> e -- | Returns a list of all the valid indices in an array. indices :: (HasBounds a, Ix i) => a i e -> [i] -- | Returns a list of all the elements of an array, in the same order as -- their indices. elems :: (IArray a e, Ix i) => a i e -> [e] -- | Returns the contents of an array as a list of associations. assocs :: (IArray a e, Ix i) => a i e -> [(i, e)] -- | Takes an array and a list of pairs and returns an array identical to -- the left argument except that it has been updated by the associations -- in the right argument. For example, if m is a 1-origin, n by n matrix, -- then m//[((i,i), 0) | i <- [1..n]] is the same matrix, -- except with the diagonal zeroed. -- -- As with the array function, if any two associations in the list -- have the same index, the value at that index is -- implementation-dependent. (In GHC, the last value specified for that -- index is used. Other implementations will also do this for unboxed -- arrays, but Haskell 98 requires that for Array the value at such -- indices is bottom.) -- -- For most array types, this operation is O(n) where n is -- the size of the array. However, the Data.Array.Diff.DiffArray type -- provides this operation with complexity linear in the number of -- updates. (//) :: (IArray a e, Ix i) => a i e -> [(i, e)] -> a i e -- | accum f takes an array and an association list and -- accumulates pairs from the list into the array with the accumulating -- function f. Thus accumArray can be defined using -- accum: -- --
--   accumArray f z b = accum f (array b [(i, z) | i \<- range b])
--   
accum :: (IArray a e, Ix i) => (e -> e' -> e) -> a i e -> [(i, e')] -> a i e -- | Returns a new array derived from the original array by applying a -- function to each of the elements. amap :: (IArray a e', IArray a e, Ix i) => (e' -> e) -> a i e' -> a i e -- | Returns a new array derived from the original array by applying a -- function to each of the indices. ixmap :: (IArray a e, Ix i, Ix j) => (i, i) -> (i -> j) -> a j e -> a i e -- | Mutable boxed and unboxed arrays in the IO monad. module Data.ArrayBZ.IO -- | Boxed mutable arrays in IO monad type IOArray = IOSpecific3 BoxedMutableArray -- | Unboxed mutable arrays in IO monad type IOUArray = IOSpecific3 UnboxedMutableArray -- | Casts an IOUArray with one element type into IOUArray -- with a different element type (upper bound is recalculated). castIOUArray :: (Ix i, Enum i, Unboxed e, Unboxed e') => IOUArray i e -> IOUArray i e' -- | Reads a number of Word8s from the specified Handle -- directly into an array. hGetArray :: Handle -> IOUArray Int Word8 -> Int -> IO Int -- | Writes an array of Word8 to the specified Handle. hPutArray :: Handle -> IOUArray Int Word8 -> Int -> IO () -- | Mutable boxed and unboxed arrays in the ST monad. module Data.ArrayBZ.ST -- | Boxed mutable arrays in ST monad type STArray = BoxedMutableArray -- | A safe way to create and work with a mutable array before returning an -- immutable array for later perusal. This function avoids copying the -- array before returning it - it uses unsafeFreeze internally, -- but this wrapper is a safe interface to that function. runSTArray :: (Ix i) => (forall s. ST s (STArray s i e)) -> Array i e -- | Unboxed mutable arrays in ST monad type STUArray = UnboxedMutableArray -- | A safe way to create and work with an unboxed mutable array before -- returning an immutable array for later perusal. This function avoids -- copying the array before returning it - it uses unsafeFreeze -- internally, but this wrapper is a safe interface to that function. runSTUArray :: (Unboxed e, HasDefaultValue e, Ix i) => (forall s. ST s (STUArray s i e)) -> UArray i e -- | Casts an STUArray with one element type into STUArray -- with a different element type (upper bound is recalculated). castSTUArray :: (Ix i, Enum i, Unboxed e, Unboxed e') => STUArray s i e -> STUArray s i e' -- | Universal interface for reading and writing mutable data (references, -- array and hash elements) Syntax sugar (=:, +=, val...) based on this -- interface module Data.SyntaxSugar class (Monad m) => Mutable m r a | r -> a readVar :: (Mutable m r a) => r -> m a writeVar :: (Mutable m r a) => r -> a -> m () -- | Modify the contents of an Mutable by applying pure function to -- it modifyVar :: (Mutable m r b) => r -> (b -> b) -> m () -- | Modify the contents of an Mutable by applying monadic -- computation to it modifyVarM :: (Mutable m r a) => r -> (a -> m a) -> m () hashUpdate :: HashTable key val -> key -> val -> IO Bool ref :: (Ref m r) => a -> m (r a) uref :: (Unboxed a, URef m r) => a -> m (r a) val :: (Mutable m r a) => r -> m a (=:) :: (Mutable m r a) => r -> a -> m () (+=) :: (Mutable m r b, Num b) => r -> b -> m () (-=) :: (Mutable m r b, Num b) => r -> b -> m () (.=) :: (Mutable m r b) => r -> (b -> b) -> m () (.<-) :: (Mutable m r a) => r -> (a -> m a) -> m () instance Mutable IO (HashTable key e, key) e instance (MArray a e m, Ix i, Ix j, Ix k) => Mutable m (a (i, j, k) e, i, j, k) e instance (MArray a e m, Ix i, Ix j) => Mutable m (a (i, j) e, i, j) e instance (Unboxed e, Ix i) => Mutable (ST s) (STUArray s i e, i) e instance (Ix i) => Mutable (ST s) (STArray s i e, i) e instance (Storable e, Ix i) => Mutable IO (StorableArray i e, i) e instance (Unboxed e, Ix i) => Mutable IO (IOUArray i e, i) e instance (Ix i) => Mutable IO (IOArray i e, i) e instance (Unboxed a) => Mutable (ST s) (STURef s a) a instance (Unboxed a) => Mutable IO (IOURef a) a instance Mutable (ST s) (STRef s a) a instance Mutable IO (IORef a) a -- | Arrays with dynamically changed bounds in IO and ST monads. module Data.ArrayBZ.Dynamic -- | Representation of dynamic array. Includes * function to calculate new -- array bounds when it needs to grow * optional value used for -- initializing new elements when array grows * reference to current -- array contents data Dynamic r a i e -- | Dynamic arrays in IO monad type DynamicIO = Dynamic IORef -- | Dynamic version of IOArray type DynamicIOArray = DynamicIO IOArray -- | Dynamic version of IOUArray type DynamicIOUArray = DynamicIO IOUArray -- | Dynamic arrays in ST monad type DynamicST s = Dynamic (STRef s) -- | Dynamic version of STArray type DynamicSTArray s = (DynamicST s) (STArray s) -- | Dynamic version of STUArray type DynamicSTUArray s = (DynamicST s) (STUArray s) -- | This type represents function that calculates new array bounds when it -- needs to grow type GrowBoundsF i = (i, i) -> i -> (i, i) -- | Create new dynamic array with default value for new cells set to -- init. f is a growing strategy and may be noGrow, -- growMinimally or growTwoTimes newDynamicArray :: (Ref t r, Ix i, MArray a e t) => GrowBoundsF i -> (i, i) -> e -> t (Dynamic r a i e) -- | Create new dynamic array where all new cells will remain -- uninitialized. f is a growing strategy and may be noGrow, -- growMinimally or growTwoTimes newDynamicArray_ :: (Ref t r, Ix i, MArray a e t) => GrowBoundsF i -> (i, i) -> t (Dynamic r a i e) -- | Extend/shrink dynamic array to new bounds resizeDynamicArray :: (Ix i, MArray a t t2, Ref t2 t1) => Dynamic t1 a i t -> (i, i) -> t2 () -- | No automatic growing at all. This growing method is compatible -- with any bounds type noGrow :: t -> t1 -> a -- | Grow minimally - only to include new index in array bounds. This -- growing method is compatible with any bounds type growMinimally :: (Ix t) => (t, t) -> t -> (t, t) -- | Grow number of elements at least 2 times. This growing method is -- compatible only with bounds belonging to class Num growTwoTimes :: (Num a, Ord a) => (a, a) -> a -> (a, a) instance (MArray a e m, Ref m r) => MArray (Dynamic r a) e m instance (HasMutableBounds a m, Ref m r) => HasMutableBounds (Dynamic r a) m -- | Attaching lock to immutable value. module Control.Concurrent.LockingBZ -- | Type constructor that attaches lock to immutable value h data WithLocking h WithLocking :: h -> !MVar () -> WithLocking h -- | Add lock to object to ensure it's proper use in concurrent threads addLocking :: h -> IO (WithLocking h) -- | Run action with locked version of object withLocking :: h -> (WithLocking h -> IO a) -> IO a -- | Define class of locking implementations, where lh holds lock around h class Locking lh h | lh -> h lock :: (Locking lh h) => lh -> (h -> IO a) -> IO a -- | Lift 1-parameter action to operation on locked variable liftLock1 :: (Locking lh h) => (h -> IO a) -> lh -> IO a -- | Lift 2-parameter action to operation on locked variable liftLock2 :: (Locking lh h) => (h -> t -> IO a) -> lh -> t -> IO a -- | Lift 3-parameter action to operation on locked variable liftLock3 :: (Locking lh h) => (h -> t -> t1 -> IO a) -> lh -> t -> t1 -> IO a -- | Lift 4-parameter action to operation on locked variable liftLock4 :: (Locking lh h) => (h -> t -> t1 -> t2 -> IO a) -> lh -> t -> t1 -> t2 -> IO a -- | Lift 5-parameter action to operation on locked variable liftLock5 :: (Locking lh h) => (h -> t -> t1 -> t2 -> t3 -> IO a) -> lh -> t -> t1 -> t2 -> t3 -> IO a instance Locking (WithLocking h) h instance (Show h) => Show (WithLocking h)