Recently I started using Haskell's Repa library, which relies heavily on type families and associated types. I can define a Repa array like this:
ghci> let x = fromListUnboxed (Z :. (5 :: Int) :. (2 :: Int)) [1..10]
and operate on it like this:
ghci> computeP $ R.map id x :: IO (Array U DIM2 Double)
AUnboxed ((Z :. 5) :. 2) (fromList [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0])
where U is an associated data type that will cause the result to be represented as an unboxed array; DIM2 is array dimension. I don't like that I have to specify a concrete dimension even though it could be deduced. Instead I would want to write something like this:
ghci> computeP $ R.map id x :: Shape sh => IO (Array U sh Double)
This is not valid, but my intention is to be able to specify array type by passing appropriate associated data type (U in this example), but leave the shape unchanged. Is something like that possible?
Does something like this work?
asArrayU :: Array U sh a -> Array U sh a
asArrayU = id
computeP $ asArrayU <$> R.map id x