packages feed

rt-0.1.0.0: src/Data/Ref/Impl.hs

{-# LANGUAGE DataKinds, MagicHash, RoleAnnotations #-}
module Data.Ref.Impl (module Data.Ref.Impl) where

import GHC.Base (MutVar#, RealWorld, sameMutVar#, isTrue#)

{-
The `r` parameter is deliberately nominal here, which prevents the use of
coerce to "safely" escape the lifetime of a reference:

> escape :: a -> RT (Ref r a)
> escape x = newRef x (return . coerce)

Would compile if the annotation was left as phantom (which is the inferred).
This is clearly not something we want to allow, so nominal it is.
-}
type role Ref nominal representational
-- Don't even expose the constructor, then it's pretty much safe?
data Ref r a = Ref (MutVar# RealWorld a)

-- It's nice that two references must clearly have the same lifetime to be equal
instance Eq (Ref r a) where
  Ref ref1# == Ref ref2# = isTrue# (sameMutVar# ref1# ref2#)