Replace ArrayArray# with either UnliftedArray# or Array#
Just to be clear, there currently is nothing named UnliftedArray#
. I would like to propose that such a thing possibly be added, with the long-term goal of deprecating and removing ArrayArray#
. The interface for it would look like this:
data UnliftedArray# (a :: TYPE 'UnliftedRep)
data MutableUnliftedArray# s (a :: TYPE 'UnliftedRep)
indexUnliftedArray# :: forall (a :: TYPE 'UnliftedRep). UnliftedArray# a -> Int# -> a
writeUnliftedArray# :: forall (a :: TYPE 'UnliftedRep). MutableUnliftedArray# s a -> Int# -> a -> State# s -> State# s
readUnliftedArray# :: forall (a :: TYPE 'UnliftedRep). MutableUnliftedArray# s a -> Int# -> State# s -> (# State# s, a #)
unsafeFreezeUnliftedArray# :: forall (a :: TYPE 'UnliftedRep). MutableUnliftedArray# s a -> State# s -> (#State# s, UnliftedArray# a#)
newUnliftedArray# :: forall (a :: TYPE 'UnliftedRep). Int# -> a -> State# s -> (# State# s, MutableUnliftedArray# s a #)
You would also have a few other things like sameMutableUnliftedArray#
, sizeofMutableArray#
, unsafeThawUnliftedArray#
, copyUnliftedArray#
, etc. The main difficulty that I see in doing this is that I'm not sure if you can tell a primop that it takes a polymorphic argument whose kind is something other than TYPE LiftedRep
. The bodies of all of the functions I listed above could simply be copied from the ArrayArray#
functions.
There are a few alternatives I've heard discussed. One is to make Array#
accepted both boxed or unboxed types. There is a brief discussion of this in the UnliftedDataTypes proposal [#point0 (0)]. Indeed, it appears that some have managed to smuggle unlifted data into Array#
already, with the caveats one would expect [#point1 (1)]. This interface would look like:
data Array# (a :: TYPE k)
data MutableArray# s (a :: TYPE k)
indexArray# :: Array# a -> Int -> a -- same as before
indexUnliftedArray# :: forall (a :: TYPE UnliftedRep). Array# a -> Int -> a
So instead of having Array#
and UnliftedArray#
as separate data types, we could have Array#
handle both cases, but we would need to make a duplicate of every function that operates on Array#
. This follows all of the appropriate rules for when levity polymorphism is allowed, and it should be backwards-compatible with the previous non-levity-polymorphic definition of Array#
. I'm not sure how many things in the GHC runtime assume that the values inside an array are lifted, so this might cause a bunch of problems. If it is possible, this approach would be kind of neat because then SmallArray#
could be similarly adapted.
Anyway, I just wanted to get this out there. I would be happy to try implementing the first proposal (involving UnliftedArray#
) at some point in the next six months. Any feedback on the idea would be appreciated. Also, any comments on how appropriate this is for someone new to contributing to GHC would be appreciated as well. Thanks.
- [=#point0 (0)] https://ghc.haskell.org/trac/ghc/wiki/UnliftedDataTypes#Parametricity
- [=#point0 (1)] https://www.reddit.com/r/haskell/comments/6v9rmg/an_unified_array_interface/dlyph4i/
Trac metadata
Trac field | Value |
---|---|
Version | 8.2.1 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |