Проблема в том, что Data.Array.Unboxed
реэкспортирует Data.Array.IArray
, и, следовательно, класс IArray
для интерфейса неизменяемого массива, но Data.Array
этого не делает (он даже не импортирует его). Поэтому, если вы используете такие функции, как bounds
, accumArray
, array
и т. Д. Только с импортированным Data.Array
, они являются мономорфными в типе массива, поэтому не возникает никакой неоднозначности (полиморфизм в типе элемента, очевидно, не представляет проблема здесь, это было бы с подходящими ограничениями класса типа). Но если вы импортируете Data.Array.Unboxed
, все эти функции получают ограничение IArray a e
, и, таким образом, перезапись может включать разные типы массивов, что приводит к разрывам. Вам необходимо исправить типы с помощью сигнатур типов, функций или правил. Как именно это решить, я не могу сказать, не увидев код.
Примечание: проверка типов изменилась с 7.4, с ghc-7.4.1, код без правила не компилируется без сигнатур типов при импорте Data.Array.Unboxed
.
Чтобы исправить типы, чтобы правило не попадало в неоднозначность, необходимо указать сигнатуры типов
- на верхнем уровне, до
applyWindow
,
- к двум локальным привязкам
paddedImage
и filteredPaddedImage
.
Вероятно, желательно и наиболее разумно, чтобы все задействованные массивы имели одинаковый тип, который может быть
- мономорфный тип, скажем
UArray (Int,Int) Int
(тип элемента также может быть Word
, ...)
- тип, мономорфный в типе массива и полиморфный в типе элемента
- тип плойморфизма в обоих
Для 1. вам просто нужно добавить подписи applyWindow :: T -> T -> T
и xxImage :: T
(где T
- требуемый тип). Для 2. вам нужно добавить два языковых расширения, FlexibleContexts
и ScopedTypeVariables
, тогда applyWindow
получит подпись
applyWindow :: forall e. (Num e, IArray UArray e)
=> UArray (Int,Int) e -> UArray (Int,Int) e -> UArray (Int,Int) e
и локальные привязки получат подпись xxImage :: UArray (Int,Int) e
. FlexibleContexts
необходим, чтобы разрешить вхождение UArray
в constarint, и ScopedTypeVariables
необходимо, чтобы ввести тип элемента в область видимости, чтобы paddedImage
и filteredPaddedImage
могли вообще получать сигнатуры типов. Для 3. требуется только ScopedTypeVariables
, тогда сигнатура типа applyWindow
будет
applyWindow :: forall a e. (Num e, IArray a e) => ...
Другой метод для принудительного использования всех массивов одного типа - использование asTypeOf
или помещение их всех в список (неиспользуемая локальная привязка), но предпочтительнее использовать сигнатуры типа IMO.
Как только все типы зафиксированы (они не обязательно должны быть одинаковыми, но тип локальных привязок должен определяться типом аргумента и результата, возможно, только типами аргумента), правило должно проверять тип. (Также может потребоваться исправить типы в indexMult
.)