Skip to content

Instantly share code, notes, and snippets.

@andrewthad
Last active September 7, 2017 16:09
Show Gist options
  • Save andrewthad/3d987f4a849d6c1f58a256b246c92dd7 to your computer and use it in GitHub Desktop.
Save andrewthad/3d987f4a849d6c1f58a256b246c92dd7 to your computer and use it in GitHub Desktop.
StableName with value in ST
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
module Example
( Stable
, stabilize
, destabilize
) where
import GHC.Prim
import GHC.ST
import GHC.Int
import Data.Hashable
import Data.Hashable.Lifted
import Data.Functor.Classes
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
instance Eq1 (Stable s) where
liftEq f (Stable sn1 a1) (Stable sn2 a2) = case eqStableName# sn1 sn2 of
0# -> f a1 a2
_ -> True
instance Hashable (Stable s a) where
hash (Stable sn _) = I# (stableNameToInt# sn)
hashWithSalt s (Stable sn _) = hashWithSalt s (I# (stableNameToInt# sn))
instance Hashable1 (Stable s) where
liftHashWithSalt _ s st = hashWithSalt s st
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment