Couldn't match type `D' with `U' in Haskell repa arrays

75 Views Asked by At

I am trying to write some simple back substitution matrix code. For this I wrote a fold operator which folds with rows.

Here is a non generic type signature of the function and its implemtation:

foldMatrixByRow :: (Array D DIM1 Double -> Array D DIM1 Double -> Int -> Array D DIM1 Double)
                    -> Array D DIM1 Double
                    -> Array U DIM2 Double
                    -> Array D DIM1 Double

foldMatrixByRow f intial mat = foldMatrixByRowUtil f intial (mat, 0)
                              where foldMatrixByRowUtil f initial (mat, i)
                                      | i == n = initial
                                      | otherwise = foldMatrixByRowUtil f result (mat, i + 1)
                                      where result = f matRow initial i
                                            matRow = delayNRow mat i
                                            (Z :. n :. _) = extent mat
  • The difference in repa's foldS, foldP etc and the above fold is, that the folding function takes 2 DIM1 delayed arrays as parameters.
  • More importantly, for aiding loop fusion it returns a delayed array (Array D DIM1 Double).

The following is the code for back substitution

backsubstitution :: Array U DIM2 Double -> Array U DIM1 Double -> Array D DIM1 Double                                                           
backsubstitution mat bs = foldMatrixByRow f initial mat
                              where  
                                    f matRow sols i = fromFunction (extent bs) intArr 
                                        where 
                                            intArr (Z :. j) | i == j = rowComp | j < i = 0.0 | otherwise = sols R.! (Z :. j) 
                                            intc = ((bs ! (Z :. i)) - (rowComp)) / (matRow ! (Z :.i))
                                            rowComp = sumAllS $ traverse2Backwards matRow sols g     
                                            g m s (i', _) = if i < i' then m * s else 0.0

                                    initial = fromFunction (extent bs) (\ _ -> 0)
  • To aid loop fusion I, on purpose make initial delayed. matRow is computed by delayNRow which also computes a delayed array (delayNRow code is supplied after the next bullet).
  • fromFunction type signature certainly returns a delayed array.

    delayNRow :: Array U DIM2 Double -> Int -> Array D DIM1 Double

    delayNRow arr n = R.slice arr (Any :. n :. All)

BUT HERE IS THE PROBLEM :

Why do I get the following error:

 Couldn't match type `D' with `U'
 Expected type: Array D DIM1 Double -> Array D DIM1 Double -> Int -> Array D DIM1 Double
 Actual type: Array U DIM1 Double  -> Array U DIM1 Double -> Int -> Array D DIM1 Double
In the first argument of `foldMatrixByRow', namely `f'
In the expression: foldMatrixByRow f initial mat
In an equation for `backsubstitution':
 In an equation for `backsubstitution':
 backsubstitution mat bs
   = foldMatrixByRow f initial mat
   where
       f matRow sols i
         = fromFunction (extent bs) intArr
         where ...

tldr; Why am I getting the error that the input to f in backsubstitution are U arrays, whereas I am providing them with arrays that are delayed (D).

0

There are 0 best solutions below