Data.Array doesn’t provide folds for the Array type.
In Real World Haskell (ch. 12), the reason is said to be that Arrays could be folded in different ways based on the programmer’s needs:
First of all, there are several kinds of folds that make sense. We might still want to fold over single elements, but we now have the possibility of folding over rows or columns, too. On top of this, for element-at-a-time folding, there are no longer just two sequences for traversal.
Isn’t this exactly true of Lists? It’s very common to represent e.g. a matrix with a multidimensional List, but there are still folds defined for one-dimensional Lists.
What’s the subtlety I’m missing? Is it that a multidimensional Array is sufficiently different from an Array of Arrays?
Edit: Hm, even multidimensional arrays do have folds defined, in the form of instances of Data.Foldable.[0] So how does that fit in with the Real World Haskell quote?
[0] http://hackage.haskell.org/packages/archive/base/4.6.0.0/doc/html/Data-Foldable.html
Since you mention the difference between a “multidimensional”
Arrayand anArrayofArrays, that will illustrate the point nicely, alongside a comparison with lists.A fold (in the
Foldableclass sense) is an inherently linear operation, just as lists are an inherently linear structure; a right fold fully characterizes a list by matching its constructors one-for-one with the arguments tofoldr. While you can define functions likefoldlas well, there’s a clear choice of a standard, canonical fold.Arrayhas no such transparent structure that can be matched one-for-one in a fold. It’s an abstract type, with access to individual elements provided by index values, which can be of any type that has anIxinstance. So not only is there no single obvious choice for implementing a fold, there also is no intrinsic linear structure. It does so happen thatIxlets you enumerate a range of indices, but this is more an implementation detail than anything else.What about multidimensional
Arrays? They don’t really exist, as such.Ixdefines instances for tuples of types that are also instances, and if you want to think of such tuples as an index type for a “multidimensional”Array, go ahead! But they’re still just tuples. Obviously,Ixputs some linear order on those tuples, but what is it? Can you find anything in the documentation that tells you?So, I think we can safely say that folding a multidimensional
Arrayusing the order defined byIxis unwise unless you don’t really care what order you get the elements in.For an
ArrayofArrays, on the other hand, there’s only one sensible way to combine them, much like nested lists: fold each innerArrayseparately according to their own order of elements, then fold the result of each according to the outerArray‘s order of elements.Now, you might reasonably object that since there’s no type distinction between one-dimensional and multidimensional
Arrays, and the former can be assumed to have a sensible fold ordering based on theIxinstance, why not just use that ordering by default? There’s already a function that returns the elements of anArrayin a list, after all.As it turns out, the library itself would agree with you, because that’s exactly what the
Foldableinstance does.