Implement mutable vectors using arrays#146
Conversation
| allocBeside :: Int -> a -> Array b #-> (Array b, Array a) | ||
| allocBeside size val orig | ||
| | size >= 0 = (orig, Array (Unsafe.newMutArr size val)) | ||
| | otherwise = orig `lseq` error ("Trying to allocate an array of size " ++ show size) |
There was a problem hiding this comment.
I find this function interesting. It is required since when implementing HashMap's, insertions can cause a new, bigger array to be created. However, we can not use alloc function there since it requires a continuation; and making HashMap insertions take a continuation would be unwieldy.
I wanted to replace it with something more generic, but couldn't figure out how to do it nicely. I think this connects to @aspiwack 's suggestion on #130.
| where | ||
| unsafeLength :: Vector a -> (Vector a, Int) | ||
| unsafeLength v@(Vec (len, _) _) = (v, len) | ||
| length :: Vector a #-> (Vector a, Unrestricted Int) |
There was a problem hiding this comment.
I replaced this function to return an Unrestricted Int instead of Int, to be more consistent with other functions like read.
|
|
||
| -- | Read from a vector, with an in-range index and error for an index that is | ||
| -- out of range (with the usual range @0..length-1@). | ||
| read :: HasCallStack => Vector a #-> Int -> (Vector a, a) |
There was a problem hiding this comment.
The new version of this function returns a Unrestricted a instead. Since the vector does not contain its values linearly, I think it was overly restrictive.
|
|
||
| data Array a where | ||
| Array :: Int -> (MutableArray# RealWorld a) -> Array a | ||
| Array :: MutableArray# RealWorld a -> Array a |
There was a problem hiding this comment.
Now the Array does not have an extra size parameter, since MutableArray# already comes with a sizeof method.
Whatever I think of this change. It didn't belong to this PR. Additionally, this is not the sort of change that you should make without talking about it first. We've all got better things to do than revert this in the course of this PR, though I do hope this sort of conflation won't happen again. But please open an issue to discuss the order of arguments in these functions. (under the bikeshedding label, I assume) |
This should have been another PR. |
|
I'm happy to spend some time sending separate PR's for each. Sorry about this. |
This PR refactors
Data.Vector.Mutable.Linearto useData.Array.Mutable.Linearinstead ofUnsafe.MutableArray. I also did a few refactors around the Array code.In summary:
unsafeReadandunsafeWritefunctions from vectors and array to reduce unnecessary bounds-checking in vector code.Arrayhad a few resize functions with counter-intutive semantics. I replaced them with three functions:allocBeside,growByandshrinkTo. Let me know if you prefer something else.MutableArray,ArrayandVectorused to require at least one element inside. I removed this constraint. It seems likeMutableArraycan have 0 length, and therefore there is no reasonArrayandVectorto have that restriction.So I'm sorry if this PR is a bit all around the place. I suggest you review the modules in this order:
Unsafe.MutableArrayData.Array.Mutable.LinearData.Vector.Mutable.Linear.Data.HashMap.Linear(only contains changes because of the parameter order change)