{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ScopedTypeVariables #-}
#include "inline.hs"
module Streamly.Internal.Mutable.Prim.Var
(
Var
, MonadMut
, Prim
, newVar
, writeVar
, modifyVar'
, readVar
)
where
import Control.Monad.Primitive (PrimMonad(..), primitive_)
import Data.Primitive.Types (Prim, sizeOf#, readByteArray#, writeByteArray#)
import GHC.Exts (MutableByteArray#, newByteArray#)
data Var m a = Var (MutableByteArray# (PrimState m))
type MonadMut = PrimMonad
{-# INLINE newVar #-}
newVar :: forall m a. (MonadMut m, Prim a) => a -> m (Var m a)
newVar x = primitive (\s# ->
case newByteArray# (sizeOf# (undefined :: a)) s# of
(# s1#, arr# #) ->
case writeByteArray# arr# 0# x s1# of
s2# -> (# s2#, Var arr# #)
)
{-# INLINE writeVar #-}
writeVar :: (MonadMut m, Prim a) => Var m a -> a -> m ()
writeVar (Var arr#) x = primitive_ (writeByteArray# arr# 0# x)
{-# INLINE readVar #-}
readVar :: (MonadMut m, Prim a) => Var m a -> m a
readVar (Var arr#) = primitive (readByteArray# arr# 0#)
{-# INLINE modifyVar' #-}
modifyVar' :: (MonadMut m, Prim a) => Var m a -> (a -> a) -> m ()
modifyVar' (Var arr#) g = primitive_ $ \s# ->
case readByteArray# arr# 0# s# of
(# s'#, a #) -> let a' = g a in a' `seq` writeByteArray# arr# 0# a' s'#