Proposed modification to 'array' function in Data.Array
In Data.Array the function array :: (IArray a e, Ix i) => (i, i) -> [(i, e)] -> a i e
takes the array bounds and an association list, and it produces an
Array
. The function allows you to build an Array by providing the elements
in whatever order you choose, rather than from the first index to the last.
The function listArray
is similar except that it assumes that the list is
already ordered by index so there is no need to provide tuples of (index,
value). Becase listArray
actually uses zip
internally to produce the
tupled list, so the programmer can pass a list to listArray
which exceeds
the declared bounds of the array and the function will quietly drop the extra
list tail:
Prelude Data.Array> listArray (1,3) ['a','b','c',undefined]
array (1,3) [(1,'a'),(2,'b'),(3,'c')]
But when a list that exceeds the specified bound is passed to array
, it dies
a horrible death:
Prelude Data.Array> array (1,3) [(1,'a'),(2,'b'),(3,'c'),(4,'d')] array
*** Exception: Error in array index
I think the array
function should be modified by adding a simple take
to
automatically drop any excess list elements:
array (l,u) ies =
let n = safeRangeSize (l,u)
in unsafeArray (l,u) [(safeIndex (l,u) n i, e) | (i, e) <- take n ies]
This change would bring the function into better alignment with other prelude
functions which expect infinite lists and drop tails as needed. It can be
argued that the programmer might want to know that he is passing too long a
list to his function, in which case I think the safeRangeSize
function, etc.
should be eliminated.