-- | -- Module: Data.HashCons.ConstRef -- Description: Read-only references -- Copyright: © 2018 Andy Morris -- Licence: BSD-3-Clause -- Maintainer: hello@andy-morris.xyz -- Stability: experimental -- Portability: GHC internals -- -- Read-only references with pointer equality. module Data.HashCons.ConstRef (ConstRef, newConstRef, readConstRef) where import Data.HashCons.MkWeak import Data.IORef (IORef, newIORef, readIORef) import System.IO.Unsafe (unsafeDupablePerformIO) -- | A read-only reference. -- -- A 'ConstRef' is similar to an 'IORef' in that it has its own identity. -- -- @ -- do a <- 'newConstRef' () -- b <- 'newConstRef' () -- 'return' '$' a '==' b -- -- 'False' -- @ -- -- However, unlike most types of reference, it is immutable and its value is set -- at construction time. This is the reason why 'readConstRef' does not need to -- return an 'IO' value. newtype ConstRef a = CR (IORef a) deriving Eq -- ^ Pointer equality -- | Make a new 'ConstRef'. newConstRef :: a -> IO (ConstRef a) newConstRef x = CR <$> newIORef x -- | Read the value of a 'ConstRef'. readConstRef :: ConstRef a -> a readConstRef (CR r) = unsafeDupablePerformIO $ readIORef r instance MkWeak (ConstRef a) where mkWeak (CR r) = mkWeak r