Нарезка массива IOArray (или массива в целом)
Есть ли способ, как эффективно построить срез (представление подмассива) из IOArray
, или же MArray
в общем? То есть, принимая тот же массив, просто ограничивая границы. Подпись может быть
(MArray a e m, Ix i) => a i e -> i -> i -> m (a i e)
Например, взять массив с границами (1,1000)
и создание представления, которое дает доступ только к элементам с границами (500,700)
оригинального массива. Я искал документацию, но я не мог найти такую функцию.
1 ответ
Учитывая, как реализованы типы массивов, это не то, что действительно было бы особенностью массива, поэтому, вероятно, ничего подобного не существует.
Напомним, что массив является непрерывным блоком памяти, поэтому на некотором уровне каждый массив с n
элементы имеют границы (0, n-1)
, Тем не менее, наличие индексов, отличных от целых чисел, начинающихся с нуля, достаточно распространено, так что Haskell предоставляет класс типов для определения произвольных границ и перевода из элемента внутри этих границ в целочисленный индекс на основе 0 для фактического блока памяти.
Это создает некоторые трудности для того, что вы хотите сделать, потому что предполагается, что границы для массива охватывают весь диапазон. Так что, если бы вы просто создали копию существующего массива, который использовал бы тот же кусок памяти, но разные границы, индексы не выровнялись бы - в вашем примере индекс 500 в подмассиве будет таким же, как индекс 1 в оригинале массив. Не полезно.
Простейший подход здесь состоит в том, чтобы определить свой собственный тип массива, который оборачивает существующий массив и хранит любую дополнительную информацию, необходимую для преобразования индексов, так что он сообщает свои собственные границы как меньший диапазон, но ищет вещи в обернутом массиве на основе полный спектр. Затем вы можете использовать тип обернутого массива везде (и дать ему все ожидаемые экземпляры и т. Д.) С вновь созданными массивами, просто используя те же границы, что и "реальный" массив. Здесь вы можете выполнять любые преобразования, которые вам нужны, для индексов, поэтому этот подход следует распространить на типы индексов, которые также не имеют линейного порядка (например, "многомерные" массивы, индексированные кортежами).
Возможно, вы могли бы также сделать что-нибудь, включающее обертку вокруг вашего индекса и дать странную версию обертки Ix
экземпляр, который как-то автоматически переводит вещи, что позволит вам использовать существующие типы массивов. Хотя, наверное, было бы сложнее заставить работать правильно.
Я не думаю, что есть какой-либо способ сделать это без изменения типа массива или индекса.