diff options
Diffstat (limited to 'src/Data/StableName')
-rw-r--r-- | src/Data/StableName/Extra.hs | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/Data/StableName/Extra.hs b/src/Data/StableName/Extra.hs index f568740..cf37cfe 100644 --- a/src/Data/StableName/Extra.hs +++ b/src/Data/StableName/Extra.hs @@ -1,10 +1,16 @@ {-# LANGUAGE BangPatterns #-} +{-# LANGUAGE ExistentialQuantification #-} {-# OPTIONS_GHC -fno-full-laziness -fno-cse #-} module Data.StableName.Extra ( StableName, makeStableName', + showStableName, ) where +import Data.Hashable +import Data.HashMap.Strict (HashMap) +import qualified Data.HashMap.Strict as HM +import Data.IORef import GHC.StableName import System.IO.Unsafe @@ -15,3 +21,24 @@ import System.IO.Unsafe {-# NOINLINE makeStableName' #-} makeStableName' :: a -> StableName a makeStableName' !x = unsafePerformIO (makeStableName x) + + +data SomeStableName = forall a. SomeStableName (StableName a) + +instance Eq SomeStableName where + SomeStableName a == SomeStableName b = eqStableName a b + +instance Hashable SomeStableName where + hashWithSalt salt (SomeStableName name) = hashWithSalt salt name + +{-# NOINLINE showStableNameCache #-} +showStableNameCache :: IORef (HashMap SomeStableName Int, Int) +showStableNameCache = unsafePerformIO $ newIORef (mempty, 0) + +{-# NOINLINE showStableName #-} +showStableName :: StableName a -> String +showStableName name = + unsafePerformIO $ atomicModifyIORef' showStableNameCache $ \tup@(mp, nexti) -> + case HM.lookup (SomeStableName name) mp of + Just res -> (tup, '$' : show res) + Nothing -> ((HM.insert (SomeStableName name) nexti mp, nexti + 1), '$' : show nexti) |