Skip to content

Generalize makeStableName#

The function makeStableName# has the following type:

makeStableName# :: a -> State# RealWorld -> (#State# RealWorld, StableName# a#)

I believe that it could safely be changed to:

makeStableName# :: a -> State# s -> (#State# s, StableName# a#)

Currently, I have some code that looks like this:

{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
module Example
  ( Stable
  , stabilize
  , destabilize
  ) where

import GHC.Prim
import GHC.ST

data Stable s a = Stable (StableName# a) a

stabilize :: a -> ST s (Stable s a)
stabilize a = ST $ \ s ->
  case makeStableName# a (unsafeCoerce# s) of (# s', sn #) -> (# unsafeCoerce# s', Stable sn a #)

destabilize :: Stable s a -> a
destabilize (Stable _ a) = a

instance Eq a => Eq (Stable s a) where
  Stable sn1 a1 == Stable sn2 a2 = case eqStableName# sn1 sn2 of
    0# -> a1 == a2
    _  -> True

I want to be working in ST, not in IO, and I believe that this use of unsafeCoerce# is safe. However, it would be nice to not have to use it at all.

Edited by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information