You may want to use the Hackage page of the Data.Primitive.Array module: https://hackage.haskell.org/package/primitive-0.8.0.0/docs/Data-Primitive-Array.html
Some relevant functions:
createArray :: Int -> a -> (forall s. MutableArray s a -> ST s ()) -> Array a
Create an array of the given size with a default value, apply the monadic function and freeze the result. If the size is 0, return emptyArray (rather than a new copy thereof).
createArray 0 _ _ = emptyArray
createArray n x f = runArray $ do
mary <- newArray n x
f mary
pure mary
thawArray
:: PrimMonad m
=> Array a -- ^ source
-> Int -- ^ offset
-> Int -- ^ length
-> m (MutableArray (PrimState m) a)
Create a mutable array from a slice of an immutable array.
This operation makes a copy of the specified slice, so it is safe to use the immutable array afterward.
Note: The provided array should contain the full subrange specified by the two Ints, but this is not checked.