Переменные внутренние типы для обернутого массива Repa
Я пытаюсь написать тонкую оболочку для repa, чтобы обеспечить дополнительные ограничения для какой-то специфичной для домена работы, которую я делаю. У меня есть тип:
newtype Tile p r a = Tile { _array :: Array r DIM2 a }
где Array
происходит от repa
, Я хотел бы скрыть r
потому что это добавляет шум к типу подписей и делает Tile
дырявая абстракция:
newtype Tile p a = Tile { _array :: Array ? DIM2 a } -- what should `?` be?
К сожалению, это r
может меняться между операциями репа. Большую часть времени это D
(для "отложенного представления"), но когда данные впервые создаются из списка или вектора, это будет U
("распакованный вектор") или V
("вектор в штучной упаковке"). Они используются в качестве подсказок типа, чтобы помочь repa оптимизировать свои операции.
Есть ли способ для меня, чтобы скрыть r
как мне хотелось бы, но позвольте ему внутренне меняться, не влияя на проверку типов с помощью моей обертки Tile
тип? Это область RankNTypes
и друзья? Я признаю, что не очень хорошо их понимаю. Чтобы быть наиболее понятным, я хотел бы иметь возможность написать:
foo :: Tile p a -> Tile p b -> Tile p c
где два Tile
аргументы содержат (например) Array U DIM2 Int
а также Array D DIM2 Int
соответственно. Это плохая вещь, чтобы желать?
1 ответ
Я смог обойти проблему, заставив завернутый Array
всегда содержать D
введите param с помощью delay
функция
Это также позволило мне сохранить Tile
как newtype
а также определить Functor
пример для этого.