Skip to content

Make Storable vectors nominally roled, and add unsafeCoerceVector functions - #235

Merged
cartazio merged 2 commits into
masterfrom
nominal
Jan 7, 2020
Merged

Make Storable vectors nominally roled, and add unsafeCoerceVector functions#235
cartazio merged 2 commits into
masterfrom
nominal

Conversation

@RyanGlScott

Copy link
Copy Markdown
Member

In #224, we came to the conclusion that Storable vectors should be nominally roled in their type arguments. This PR implements that. I've also added unsafeCoerce{M}Vector functions which allow one to coerce between two Storable vectors in the event where you (the programmer) can ensure that the two Storable instances you're coercing between have identical memory representations.

There's still an open question about what to name these unsafeCoerce{M}Vector functions—suggestions welcome.

@cartazio

Copy link
Copy Markdown
Contributor

@RyanGlScott do we still need to do this change in master?

@RyanGlScott

Copy link
Copy Markdown
MemberAuthor

Yes. Also, opinions about what to name these functions are welcome.

@cartazio
cartazio merged commit c8d2d94 into masterJan 7, 2020
@RyanGlScott
RyanGlScott deleted the nominal branch January 7, 2020 17:02
@RyanGlScottRyanGlScott mentioned this pull request Jan 30, 2020
Shimuuar added a commit to Shimuuar/vector that referenced this pull request Jun 13, 2020
Reasoning is identical to one for storable vectors. See discussion in haskell#224, and
PR haskell#235.
Fixeshaskell#277
Shimuuar added a commit to Shimuuar/vector that referenced this pull request Jun 14, 2020
Reasoning is identical to one for storable vectors. See discussion in haskell#224, and
PR haskell#235.
Fixeshaskell#277
Shimuuar added a commit to Shimuuar/vector that referenced this pull request Jun 14, 2020
Reasoning is identical to one for storable vectors. See discussion in haskell#224, and
PR haskell#235.
Fixeshaskell#277
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Aug 19, 2022
# Changes in version 0.13.0.0
* `mkType` from `Data.Vector.Generic` is deprecated in favor of
`Data.Data.mkNoRepType`
* The role signatures on several `Vector` types were too permissive, so they
have been tightened up:
* The role signature for `Data.Vector.Mutable.MVector` is now
`type role MVector nominal representational` (previously, both arguments
were `phantom`). [#224](haskell/vector#224)
* The role signature for `Data.Vector.Primitive.Vector` is now
`type role Vector nominal` (previously, it was `phantom`).
The role signature for `Data.Vector.Primitive.Mutable.MVector` is now
`type role MVector nominal nominal` (previously, both arguments were
`phantom`). [#316](haskell/vector#316)
* The role signature for `Data.Vector.Storable.Vector` is now
`type role Vector nominal` (previous, it was `phantom`), and the signature
for `Data.Vector.Storable.Mutable.MVector` is now
`type role MVector nominal nominal` (previous, both arguments were
`phantom`). [#235](haskell/vector#235)
We pick `nominal` for the role of the last argument instead of
`representational` since the internal structure of a `Storable` vector is
determined by the `Storable` instance of the element type, and it is not
guaranteed that the `Storable` instances between two representationally
equal types will preserve this internal structure. One consequence of this
choice is that it is no longer possible to `coerce` between
`Storable.Vector a` and `Storable.Vector b` if `a` and `b` are nominally
distinct but representationally equal types. We now provide
`unsafeCoerce{M}Vector` and `unsafeCast` functions to allow this (the onus
is on the user to ensure that no `Storable` invariants are broken when
using these functions).
* Methods of type classes `Data.Vector.Generic.Mutable.MVector` and
`Data.Vector.Generic.Vector` use concrete monads (`ST`, etc) istead of being
polymorphic (`PrimMonad`, etc). [#335](haskell/vector#335).
This makes it possible to derive `Unbox` with:
* `GeneralizedNewtypeDeriving`
* via `UnboxViaPrim` and `Prim` instance
* via `As` and `IsoUnbox` instance: [#378](haskell/vector#378)
* Add `MonadFix` instance for boxed vectors: [#312](haskell/vector#312)
* Re-export `PrimMonad` and `RealWorld` from mutable vectors:
[#320](haskell/vector#320)
* Add `maximumOn` and `minimumOn`: [#356](haskell/vector#356)
* The functions `scanl1`, `scanl1'`, `scanr1`, and `scanr1'` for immutable
vectors are now defined when given empty vectors as arguments,
in which case they return empty vectors. This new behavior is consistent
with the one of the corresponding functions in `Data.List`.
Prior to this change, applying an empty vector to any of those functions
resulted in an error. This change was introduced in:
[#382](haskell/vector#382)
* Change allocation strategy for `unfoldrN`: [#387](haskell/vector#387)
* Remove `CPP` driven error reporting in favor of `HasCallStack`:
[#397](haskell/vector#397)
* Remove redundant `Storable` constraints on to/from `ForeignPtr` conversions:
[#394](haskell/vector#394)
* Add `unsafeCast` to `Primitive` vectors: [#401](haskell/vector#401)
* Make `(!?)` operator strict: [#402](haskell/vector#402)
* Add `readMaybe`: [#425](haskell/vector#425)
* Add `groupBy` and `group` for `Data.Vector.Generic` and the specialized
version in `Data.Vector`, `Data.Vector.Unboxed`, `Data.Vector.Storable` and
`Data.Vector.Primitive`. [#427](haskell/vector#427)
* Add `toArraySlice` and `unsafeFromArraySlice` functions for conversion to and
from the underlying boxed `Array`: [#434](haskell/vector#434)
msk pushed a commit to msk/pkgsrc that referenced this pull request May 11, 2026
# Changes in version 0.13.0.0
* `mkType` from `Data.Vector.Generic` is deprecated in favor of
`Data.Data.mkNoRepType`
* The role signatures on several `Vector` types were too permissive, so they
have been tightened up:
* The role signature for `Data.Vector.Mutable.MVector` is now
`type role MVector nominal representational` (previously, both arguments
were `phantom`). [#224](haskell/vector#224)
* The role signature for `Data.Vector.Primitive.Vector` is now
`type role Vector nominal` (previously, it was `phantom`).
The role signature for `Data.Vector.Primitive.Mutable.MVector` is now
`type role MVector nominal nominal` (previously, both arguments were
`phantom`). [#316](haskell/vector#316)
* The role signature for `Data.Vector.Storable.Vector` is now
`type role Vector nominal` (previous, it was `phantom`), and the signature
for `Data.Vector.Storable.Mutable.MVector` is now
`type role MVector nominal nominal` (previous, both arguments were
`phantom`). [#235](haskell/vector#235)
We pick `nominal` for the role of the last argument instead of
`representational` since the internal structure of a `Storable` vector is
determined by the `Storable` instance of the element type, and it is not
guaranteed that the `Storable` instances between two representationally
equal types will preserve this internal structure. One consequence of this
choice is that it is no longer possible to `coerce` between
`Storable.Vector a` and `Storable.Vector b` if `a` and `b` are nominally
distinct but representationally equal types. We now provide
`unsafeCoerce{M}Vector` and `unsafeCast` functions to allow this (the onus
is on the user to ensure that no `Storable` invariants are broken when
using these functions).
* Methods of type classes `Data.Vector.Generic.Mutable.MVector` and
`Data.Vector.Generic.Vector` use concrete monads (`ST`, etc) istead of being
polymorphic (`PrimMonad`, etc). [#335](haskell/vector#335).
This makes it possible to derive `Unbox` with:
* `GeneralizedNewtypeDeriving`
* via `UnboxViaPrim` and `Prim` instance
* via `As` and `IsoUnbox` instance: [#378](haskell/vector#378)
* Add `MonadFix` instance for boxed vectors: [#312](haskell/vector#312)
* Re-export `PrimMonad` and `RealWorld` from mutable vectors:
[#320](haskell/vector#320)
* Add `maximumOn` and `minimumOn`: [#356](haskell/vector#356)
* The functions `scanl1`, `scanl1'`, `scanr1`, and `scanr1'` for immutable
vectors are now defined when given empty vectors as arguments,
in which case they return empty vectors. This new behavior is consistent
with the one of the corresponding functions in `Data.List`.
Prior to this change, applying an empty vector to any of those functions
resulted in an error. This change was introduced in:
[#382](haskell/vector#382)
* Change allocation strategy for `unfoldrN`: [#387](haskell/vector#387)
* Remove `CPP` driven error reporting in favor of `HasCallStack`:
[#397](haskell/vector#397)
* Remove redundant `Storable` constraints on to/from `ForeignPtr` conversions:
[#394](haskell/vector#394)
* Add `unsafeCast` to `Primitive` vectors: [#401](haskell/vector#401)
* Make `(!?)` operator strict: [#402](haskell/vector#402)
* Add `readMaybe`: [#425](haskell/vector#425)
* Add `groupBy` and `group` for `Data.Vector.Generic` and the specialized
version in `Data.Vector`, `Data.Vector.Unboxed`, `Data.Vector.Storable` and
`Data.Vector.Primitive`. [#427](haskell/vector#427)
* Add `toArraySlice` and `unsafeFromArraySlice` functions for conversion to and
from the underlying boxed `Array`: [#434](haskell/vector#434)
jperkin pushed a commit to TritonDataCenter/pkgsrc that referenced this pull request May 14, 2026
# Changes in version 0.13.0.0
* `mkType` from `Data.Vector.Generic` is deprecated in favor of
`Data.Data.mkNoRepType`
* The role signatures on several `Vector` types were too permissive, so they
have been tightened up:
* The role signature for `Data.Vector.Mutable.MVector` is now
`type role MVector nominal representational` (previously, both arguments
were `phantom`). [#224](haskell/vector#224)
* The role signature for `Data.Vector.Primitive.Vector` is now
`type role Vector nominal` (previously, it was `phantom`).
The role signature for `Data.Vector.Primitive.Mutable.MVector` is now
`type role MVector nominal nominal` (previously, both arguments were
`phantom`). [#316](haskell/vector#316)
* The role signature for `Data.Vector.Storable.Vector` is now
`type role Vector nominal` (previous, it was `phantom`), and the signature
for `Data.Vector.Storable.Mutable.MVector` is now
`type role MVector nominal nominal` (previous, both arguments were
`phantom`). [#235](haskell/vector#235)
We pick `nominal` for the role of the last argument instead of
`representational` since the internal structure of a `Storable` vector is
determined by the `Storable` instance of the element type, and it is not
guaranteed that the `Storable` instances between two representationally
equal types will preserve this internal structure. One consequence of this
choice is that it is no longer possible to `coerce` between
`Storable.Vector a` and `Storable.Vector b` if `a` and `b` are nominally
distinct but representationally equal types. We now provide
`unsafeCoerce{M}Vector` and `unsafeCast` functions to allow this (the onus
is on the user to ensure that no `Storable` invariants are broken when
using these functions).
* Methods of type classes `Data.Vector.Generic.Mutable.MVector` and
`Data.Vector.Generic.Vector` use concrete monads (`ST`, etc) istead of being
polymorphic (`PrimMonad`, etc). [#335](haskell/vector#335).
This makes it possible to derive `Unbox` with:
* `GeneralizedNewtypeDeriving`
* via `UnboxViaPrim` and `Prim` instance
* via `As` and `IsoUnbox` instance: [#378](haskell/vector#378)
* Add `MonadFix` instance for boxed vectors: [#312](haskell/vector#312)
* Re-export `PrimMonad` and `RealWorld` from mutable vectors:
[#320](haskell/vector#320)
* Add `maximumOn` and `minimumOn`: [#356](haskell/vector#356)
* The functions `scanl1`, `scanl1'`, `scanr1`, and `scanr1'` for immutable
vectors are now defined when given empty vectors as arguments,
in which case they return empty vectors. This new behavior is consistent
with the one of the corresponding functions in `Data.List`.
Prior to this change, applying an empty vector to any of those functions
resulted in an error. This change was introduced in:
[#382](haskell/vector#382)
* Change allocation strategy for `unfoldrN`: [#387](haskell/vector#387)
* Remove `CPP` driven error reporting in favor of `HasCallStack`:
[#397](haskell/vector#397)
* Remove redundant `Storable` constraints on to/from `ForeignPtr` conversions:
[#394](haskell/vector#394)
* Add `unsafeCast` to `Primitive` vectors: [#401](haskell/vector#401)
* Make `(!?)` operator strict: [#402](haskell/vector#402)
* Add `readMaybe`: [#425](haskell/vector#425)
* Add `groupBy` and `group` for `Data.Vector.Generic` and the specialized
version in `Data.Vector`, `Data.Vector.Unboxed`, `Data.Vector.Storable` and
`Data.Vector.Primitive`. [#427](haskell/vector#427)
* Add `toArraySlice` and `unsafeFromArraySlice` functions for conversion to and
from the underlying boxed `Array`: [#434](haskell/vector#434)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@RyanGlScott@cartazio