3 ms·
>> I take it multidimensional arrays aren't common data structures in Haskell? > Nope. They're not a core type in the language, and while I did see some packag
by nybble41 5y ago
>> I take it multidimensional arrays aren't common data structures in Haskell?
> Nope. They're not a core type in the language, and while I did see some packages on a quick search, they unfortunately seem pretty limited. They're either limited to 2 dimensions or low lengths per dimension.
The Data.Array module from the `array` package[0] provides arrays for arbitrary "index" types implementing the Ix interface, which includes tuples of arbitrary Ix types for multi-dimensional arrays. Instances of Ix are defined generically for tuples of up to five elements (for five-dimensional arrays) but you can always define more (orphan) instances, or use a custom Ix type with more than five parameters, or even nest tuples so that your index looks like ((a, b, c), (d, e, f), (g, h, i)), which I believe would be equivalent to the 9-tuple index (a, b, c, d, e, f, g, h, i).
For vectors with sizes determined at the type level you have Data.Vector.Sized from the `vector-sized` package[1]. This does not directly support multi-dimensional indices as the size type parameter must be of kind KnownNat, but they can be nested, and the type-level size information implies that all the nested vectors will be the same length.
[0] https://hackage.haskell.org/package/array-0.5.4.0/docs/Data-Array.html https://hackage.haskell.org/package/array-0.5.4.0/docs/Data-...
[1] https://hackage.haskell.org/package/vector-sized-1.4.4/docs/Data-Vector-Sized.html https://hackage.haskell.org/package/vector-sized-1.4.4/docs/...
- jolmg 5y ago> `vector-sized` package[1]. This does not directly support multi-dimensional indices as the size type parameter must be of kind KnownNat, but they can be nested, Oh! That's neat. Nesting would eliminate the need for a list at the type level, and it seems to handle numbers at the type level. That's probably sufficient to write something like a function type (a -> b -> c) -> Vector x a -> Vector y b -> Vector x (Vector y c) Perhaps it can be an operator that can be chained setting the first argument to always be `(,)`. That might roughly do what the comma does in Julia's multidimensional comprehensions. The only bad part of this is that one wouldn't be able to define a Functor instance that works with arbitrary dimensions. It'd have to be one instance for 2 dimensions, one instance for 3 dimensions, etc. For that, I think a list at the type level holding the dimensions would be necessary. EDIT: No, the nesting would prevent proper chaining mentioned operator. Using such an operator twice would result in something like `Vector z (Vector y (Vector x (a, b), c))` instead of the slightly more desirable `Vector z (Vector y (Vector x (a, (b, c)))` that I was thinking. AFAICT, it doesn't seem that either of those suggestions is sufficient for type-safe multidimensional comprehensions in Haskell. They're better than what I found, but they still have their limitations.