
#14716: indexM-style accessor for arrays? -------------------------------------+------------------------------------- Reporter: Zemyla | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: Component: libraries | Version: 8.2.2 (other) | Keywords: array | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- 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 {{{#!hs 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 {{{#!hs (!?) :: (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: {{{#!hs 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. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14716 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler