Variable inner types for wrapped Repa array

51 views Asked by At

I'm attempting to write a thin wrapper around repa to provide extra constraints for some domain-specific work I'm doing. I have the type:

newtype Tile p r a = Tile { _array :: Array r DIM2 a }

where Array comes from repa. I'd like to hide the r because it adds noise to type signatures and makes Tile a leaky abstraction:

newtype Tile p a = Tile { _array :: Array ? DIM2 a }  -- what should `?` be?

Unfortunately, that r can change between repa operations. Most of the time it's D (for "delayed representation"), but when the data is first created from a list or vector it would be U ("unboxed vector") or V ("boxed vector"). These are used as type hints to help repa optimize its operations.

Is there a way for me to hide the r as I'd like, but allow it to vary naturally internally without affecting typechecking with my wrapper Tile type? Is this the domain of RankNTypes and friends? I'll admit I don't understand them very well. To be the most clear, I'd like to be able to write:

foo :: Tile p a -> Tile p b -> Tile p c

where the two Tile arguments contain (for instance) an Array U DIM2 Int and Array D DIM2 Int respectively. Is this a bad thing to desire?

1

There are 1 answers

0
Colin Woodbury On

I was able to get around the issue by forcing the wrapped Array to always contain the D type param by using the delay function.

This also allowed me to keep Tile as a newtype and also define a Functor instance for it.