haskell / vector

An efficient implementation of Int-indexed arrays (both mutable and immutable), with a powerful loop optimisation framework .
Other
367 stars 139 forks source link

Add `unsafeToArray` function for getting the underlying boxed `Array` #434

Closed lehins closed 2 years ago

lehins commented 2 years ago

245 requested access to Vector constructor. There are a few other requests like that, see this https://github.com/haskell/vector/issues/357#issue-787733102

However, there is a universal agreement that ability to construct a very unsafe Vector with a regular type constructor is unsettling to say the least. See this: https://github.com/haskell/vector/issues/245#issuecomment-492753908 and this https://github.com/haskell/vector/issues/49#issuecomment-62709758 Let's be honest, creating an Internal module just for constructors is not going to happen and separating all unsafe functions into Unsafe module is lost cause too, see #361

The next best thing we can do, I think, is to create a couple of unsafe* functions that let users create/access underlying buffers in the unsafe way, similar to unsafeToForeignPtr.

This PR implements what I suggest, but only for immutable boxed vector. Mutable vector constructor have been exported since inception, so might as well leave it be.

chessai commented 2 years ago

This looks good, but I've always wanted the following in vector as well:

-- performs a copy, for when I no longer need slicing
toArray :: Vector a -> Array a

-- provided by this PR, not sure what warrants "unsafe". surely using the result of this function would be potentially unsafe, but this function alone shouldn't be, as far as I can tell
unsafeToArray :: Vector a -> (Array a, Int, Int)

-- construct a vector with offset 0 and length equal to the array
fromArray :: Array a -> Vector a

-- unsafe because of manual slicing
unsafeFromArray :: Array a -> Int -> Int -> Vector a
Shimuuar commented 2 years ago

Indeed, there's nothing unsafe with unsafeToArray. Only construction is unsafe. And we may add constructor in both unsafe and variety

-- Throws exception if slice is invalid
fromArraySlice :: Array a -> Int -> Int -> Vector a
-- unsafe because of manual slicing
unsafeFromArraySlice :: Array a -> Int -> Int -> Vector a
lehins commented 2 years ago

not sure what warrants "unsafe". surely using the result of this function would be potentially unsafe, but this function alone shouldn't be, as far as I can tell

This is very good point. I'll rename it to toArraySlice

-- performs a copy, for when I no longer need slicing toArray :: Vector a -> Array a

-- construct a vector with offset 0 and length equal to the array fromArray :: Array a -> Vector a

These two functions have been added in 0.12.2

-- unsafe because of manual slicing unsafeFromArray :: Array a -> Int -> Int -> Vector a

I'll add it as well, except for consistency I'll name it unsafeFromArraySlice as @Shimuuar suggested.

-- Throws exception if slice is invalid fromArraySlice :: Array a -> Int -> Int -> Vector a

I don't want to add another partial function like that. It is always possible to achieve the same with slice i n . fromArray

lehins commented 2 years ago

Addressed all the feedback. This PR is ready for a followup review.