X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=System%2FMem%2FStableName.hs;h=f0919f958fcaa8b07559ec192309fa1b7145bc7f;hb=6b1a36a595eddf1e124529646afdb75c76a9966d;hp=12d2df14a92ac8cae14e40c6d191f64a0a5a2e59;hpb=7f1f4e7a695c402ddd3a1dc2cc7114e649a78ebc;p=haskell-directory.git diff --git a/System/Mem/StableName.hs b/System/Mem/StableName.hs index 12d2df1..f0919f9 100644 --- a/System/Mem/StableName.hs +++ b/System/Mem/StableName.hs @@ -1,38 +1,81 @@ ----------------------------------------------------------------------------- --- +-- | -- Module : System.Mem.StableName -- Copyright : (c) The University of Glasgow 2001 --- License : BSD-style (see the file libraries/core/LICENSE) +-- License : BSD-style (see the file libraries/base/LICENSE) -- -- Maintainer : libraries@haskell.org -- Stability : experimental -- Portability : non-portable -- --- $Id: StableName.hs,v 1.1 2001/06/28 14:15:04 simonmar Exp $ --- --- Giving an object a stable (GC-invariant) name. +-- Stable names are a way of performing fast (O(1)), not-quite-exact +-- comparison between objects. +-- +-- Stable names solve the following problem: suppose you want to build +-- a hash table with Haskell objects as keys, but you want to use +-- pointer equality for comparison; maybe because the keys are large +-- and hashing would be slow, or perhaps because the keys are infinite +-- in size. We can\'t build a hash table using the address of the +-- object as the key, because objects get moved around by the garbage +-- collector, meaning a re-hash would be necessary after every garbage +-- collection. -- ------------------------------------------------------------------------------ +------------------------------------------------------------------------------- -module System.Mem.StableName - ( StableName {-a-} -- abstract, instance of Eq - , makeStableName -- :: a -> IO (StableName a) - , hashStableName -- :: StableName a -> Int - ) where +module System.Mem.StableName ( + -- * Stable Names + StableName, + makeStableName, + hashStableName, + ) where import Prelude +import Data.Typeable + +#ifdef __HUGS__ +import Hugs.Stable +#endif + #ifdef __GLASGOW_HASKELL__ -import GHC.Base ( Int(..) ) import GHC.IOBase ( IO(..) ) -import GHC.Prim ( StableName#, makeStableName# +import GHC.Base ( Int(..), StableName#, makeStableName# , eqStableName#, stableNameToInt# ) ----------------------------------------------------------------------------- -- Stable Names +{-| + An abstract name for an object, that supports equality and hashing. + + Stable names have the following property: + + * If @sn1 :: StableName@ and @sn2 :: StableName@ and @sn1 == sn2@ + then @sn1@ and @sn2@ were created by calls to @makeStableName@ on + the same object. + + The reverse is not necessarily true: if two stable names are not + equal, then the objects they name may still be equal. + + Stable Names are similar to Stable Pointers ("Foreign.StablePtr"), + but differ in the following ways: + + * There is no @freeStableName@ operation, unlike "Foreign.StablePtr"s. + Stable names are reclaimed by the runtime system when they are no + longer needed. + + * There is no @deRefStableName@ operation. You can\'t get back from + a stable name to the original Haskell object. The reason for + this is that the existence of a stable name for an object does not + guarantee the existence of the object itself; it can still be garbage + collected. +-} + data StableName a = StableName (StableName# a) + +-- | Makes a 'StableName' for an arbitrary object. The object passed as +-- the first argument is not evaluated by 'makeStableName'. makeStableName :: a -> IO (StableName a) #if defined(__PARALLEL_HASKELL__) makeStableName a = @@ -42,6 +85,10 @@ makeStableName a = IO $ \ s -> case makeStableName# a s of (# s', sn #) -> (# s', StableName sn #) #endif +-- | Convert a 'StableName' to an 'Int'. The 'Int' returned is not +-- necessarily unique; several 'StableName's may map to the same 'Int' +-- (in practice however, the chances of this are small, so the result +-- of 'hashStableName' makes a good hash key). hashStableName :: StableName a -> Int #if defined(__PARALLEL_HASKELL__) hashStableName (StableName sn) = @@ -63,5 +110,5 @@ instance Eq (StableName a) where #endif /* __GLASGOW_HASKELL__ */ -#include "Dynamic.h" +#include "Typeable.h" INSTANCE_TYPEABLE1(StableName,stableNameTc,"StableName")