Ix
Класс типов требует внедрения только значений типа i
и Int
. index
вместе с range
может дать нам обратное отображение:
index' :: (Ix i) => (i, i) -> Int -> i
index' b x = range b ! x
Как видите, index'
оценивает по крайней мере в линейном времени. Также мы не можем иметь представление о том, как долго работает range b
. Он оценивается способом, который пользователь определил в определении экземпляра. Таким образом, оптимизация, необходимая в вашем случае (получение средней точки массива), может иметь место, если и только если у нас есть какой-то index'
, который работает в постоянном времени. Так как класс типов Ix
не дает нам постоянное отображение времени от Int
до i
, мы должны попросить об этом пользователя. Рассмотрим следующий код:
midpoint :: (Ix j) => (Int -> j) -> Array j e -> e
midpoint f a = a ! f middle
where middle = rangeSize (bounds a) `div` 2
Теперь сложность получения средней точки массива зависит от сложности пользовательской f
. Таким образом, если значения нашего типа индекса i
могут быть в постоянном времени оценены из Int
значений и наоборот - мы получаем среднюю точку в постоянном времени.
Также рассмотрим функцию ixmap
от Data.Ix
:
ixmap :: (Ix i, Ix j) => (i, i) -> (i -> j) -> Array j e -> Array i e