indexM-style accessor for arrays?
Pretty much everything I've seen being done with basic Array
s says something along the lines of "You have to force the argument; otherwise, you get a thunk that holds a reference to the array". An example of that is fromArray
in Data.Sequence
.
But it really shouldn't be this way. The Array
from primitive
and the Vector
s from vector
have ways of obtaining a value from an array that doesn't leave a thunk hanging around. The basic prototype is
indexArrayM :: Monad m => Array a -> Int -> m a
And having this sort of thing available for standard Array
s would be useful because Array
is one of the first packages users see when they look for something like arrays in Haskell. Also, it's tagged Trustworthy
, unlike primitive
or vector
, and there are references to them in containers
, which is again a package lots of people use. It'd also mean that the Functor
, Foldable
, and Traversable
instances don't leak memory.
As a sort-of-related side note, we should also have a function (!?)
, which functions like the similarly-named function in vector
, and has the signature
(!?) :: (IArray a e, Ix i) => a i e -> i -> Maybe e
This would, in addition to not leaving a thunk when the Maybe
is deconstructed, also eliminate a common use pattern when it comes to arrays: The user of (!)
checks the bounds of the array, does something if it's outside, then passes the index to (!)
which... checks the bounds again. Having a function which works like lookup
on Map
s would be a boon here.
Having this work for all IArray
s, not just Array
, would require a new function in the IArray
typeclass, which might break existing packages that derive a new IArray
. However, the function added could be along the lines of:
unsafeAtM :: (Applicative f, Ix i) => a i e -> i -> f e
unsafeAtM a i f = pure (unsafeAt a i)
which would be a default that, while it doesn't grant the benefits of using a monadic-type accessor, would ensure the code doesn't break while the packages that use/derive it are upgraded.
Trac metadata
Trac field | Value |
---|---|
Version | 8.2.2 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries (other) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |