Can someone please explain the following code? to retrieve the diagonal of a matrix using haskell?

131 views Asked by At
mainDiag :: [[a]] -> [a]
mainDiag x = zipWith (!!) x [0..]

Can someone please explain this code (particularly zipWith (!!)) and how it returns the diagonal of the matrix?

2

There are 2 answers

0
lsmor On BEST ANSWER

zipWith takes a two parameter function and two list. Returns the list of the results of applying the function to each pair of arguments comming from each list. Example:

zipWith (+) [1,2,3] [4,5,6] = [5,7,9] -- [1 + 4, 2 + 5, 3 + 6] 

Using your example

mainDiag :: [[a]] -> [a]
mainDiag x = zipWith (!!) x [0..]

mainDiag [[1,2,3],[4,5,6], [7,8,9]] = [[1,2,3] !! 0, [4,5,6] !! 1, [7,8,9] !! 2] -- expanding the expresion
                                    = [1, 5, 9] 
0
chi On

Using informal notation, you can visualize zipWith as this:

zipWith f [x0,x1,x2,...] [y0,y1,y2,...] = [f x0 y0, f x1 y1, f x2 y2, ...]

In your case, zipWith (!!) x [0..] we have

x = [x0,x1,x2,...]
[0,1,2,...] = [y0,y1,y2]  (that is yn=n for all natural n)
(!!) = f

Hence, the result is

[(!!) x0 0, (!!) x1 1, (!!) x2 2, ...]

which is also written as

[x0 !! 0, x1 !! 1, x2 !! 2, ...]

This list contains the element in position 0 from the list x0, the one in position 1 from list x1, and so on. This is, therefore, the diagonal of the original list-of-lists x.