module Control.Monad.ST.Combinators
       ( newArray
       , (.=), (.%=), (%!), arrayToList
       , module Control.Monad.ST.Strict
       , module Data.STRef.Strict
       ) where
import           Control.Monad           ((<=<))
import           Control.Monad.ST.Strict
import           Data.STRef.Strict
import qualified Data.Vector             as V
import qualified Data.Vector.Mutable     as MV
import           Prelude

type ArrayRef s a = STRef s (V.MVector s a)

newArray :: [a] -> ST s (ArrayRef s a)
newArray :: [a] -> ST s (ArrayRef s a)
newArray = MVector s a -> ST s (ArrayRef s a)
forall a s. a -> ST s (STRef s a)
newSTRef (MVector s a -> ST s (ArrayRef s a))
-> ([a] -> ST s (MVector s a)) -> [a] -> ST s (ArrayRef s a)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Vector a -> ST s (MVector s a)
forall (m :: * -> *) a.
PrimMonad m =>
Vector a -> m (MVector (PrimState m) a)
V.unsafeThaw (Vector a -> ST s (MVector s a))
-> ([a] -> Vector a) -> [a] -> ST s (MVector s a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Vector a
forall a. [a] -> Vector a
V.fromList
{-# INLINE newArray #-}

arrayToList :: ArrayRef s a -> ST s [a]
arrayToList :: ArrayRef s a -> ST s [a]
arrayToList = (Vector a -> [a]) -> ST s (Vector a) -> ST s [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> [a]
forall a. Vector a -> [a]
V.toList (ST s (Vector a) -> ST s [a])
-> (MVector s a -> ST s (Vector a)) -> MVector s a -> ST s [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVector s a -> ST s (Vector a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
V.unsafeFreeze (MVector s a -> ST s [a])
-> (ArrayRef s a -> ST s (MVector s a)) -> ArrayRef s a -> ST s [a]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ArrayRef s a -> ST s (MVector s a)
forall s a. STRef s a -> ST s a
readSTRef
{-# INLINE arrayToList #-}

(.=) :: STRef s a -> a -> ST s ()
.= :: STRef s a -> a -> ST s ()
(.=) = STRef s a -> a -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef
{-# INLINE (.=) #-}

(.%=) :: STRef s a -> (a -> a) -> ST s ()
.%= :: STRef s a -> (a -> a) -> ST s ()
(.%=) = STRef s a -> (a -> a) -> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef'
{-# INLINE (.%=) #-}

(%!) :: ArrayRef s a -> Int -> ST s a
ArrayRef s a
v %! :: ArrayRef s a -> Int -> ST s a
%! Int
i = (MVector s a -> Int -> ST s a) -> Int -> MVector s a -> ST s a
forall a b c. (a -> b -> c) -> b -> a -> c
flip MVector s a -> Int -> ST s a
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
MV.read Int
i (MVector s a -> ST s a) -> ST s (MVector s a) -> ST s a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ArrayRef s a -> ST s (MVector s a)
forall s a. STRef s a -> ST s a
readSTRef ArrayRef s a
v
{-# INLINE (%!) #-}