Skip to content

indexM-style accessor for arrays?

Pretty much everything I've seen being done with basic Arrays 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 Vectors 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 Arrays 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 Maps would be a boon here.

Having this work for all IArrays, 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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information