From 4c5ed51a82ec288b3e2aeff480de5de48eafd37e Mon Sep 17 00:00:00 2001 From: simonmar Date: Mon, 27 May 2002 14:54:27 +0000 Subject: [PATCH] [project @ 2002-05-27 14:54:27 by simonmar] Add documentation --- System/Mem/StableName.hs | 58 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/System/Mem/StableName.hs b/System/Mem/StableName.hs index 29918c5..659dacb 100644 --- a/System/Mem/StableName.hs +++ b/System/Mem/StableName.hs @@ -8,15 +8,26 @@ -- Stability : experimental -- Portability : non-portable -- --- 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 @@ -30,8 +41,37 @@ import GHC.Base ( Int(..), StableName#, makeStableName# ----------------------------------------------------------------------------- -- 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 = @@ -41,6 +81,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) = -- 1.7.10.4