packages feed

primdata-0.1.2.2: Data/Ref/L.hs

{-# language
  UnboxedTuples, TypeOperators, MagicHash, RankNTypes,
  TypeApplications, ScopedTypeVariables, BangPatterns, BlockArguments,
  RoleAnnotations, TypeFamilies, AllowAmbiguousTypes #-}

module Data.Ref.L where

import GHC.Exts

import Data.Unlifted
import IO
import Data.Internal.Errors

type role Ref representational
data Ref a = Ref (MutVar# RealWorld a)

instance Unlifted (Ref a) where
  type Rep (Ref a) = MutVar# RealWorld a
  to# (Ref r) = r
  {-# inline to# #-}
  from# r = Ref r
  {-# inline from# #-}
  defaultElem = runIO (new undefElem)
  {-# noinline defaultElem #-}

new :: a -> IO (Ref a)
new a = IO (\s -> case newMutVar# a s of
  (# s , r #) -> (# s, Ref r #))
{-# inline new #-}

write :: Ref a -> a -> IO ()
write (Ref r) a = IO (\s -> case writeMutVar# r a s of s -> (# s, () #))
{-# inline write #-}

read :: Ref a -> IO a
read (Ref r) = IO (readMutVar# r)
{-# inline read #-}

modify :: Ref a -> (a -> a) -> IO ()
modify (Ref r) f = IO (\s -> case readMutVar# r s of
  (# s, a #) -> case writeMutVar# r (f a) s of
    s -> (# s, () #))
{-# inline modify #-}

modify' :: Ref a -> (a -> a) -> IO ()
modify' (Ref r) f = IO (\s -> case readMutVar# r s of
  (# s, a #) -> let !a' = f a in case writeMutVar# r a' s of
    s -> (# s, () #))
{-# inline modify' #-}