Remember that map
requires a procedure that takes as many arguments as you have lists to map. In this case we want to access the i
th element of a list, this is the built-in procedure list-ref
which takes a list L
and an index i
and returns the i
th element of L
. So then we just need the indexes of the diagonal elements. This is (list 0 1 2 ...)
which we can generate using build-list
.
(define (diagonal M)
(define indexes (build-list (length M) values))
(map list-ref M indexes))
You don't have to build the second list if you use recursion. In this case you build the diagonal in a recursive function where we take the leading element of the first row, then recur on the rest of the elements in the rest of the rows:
(define (diagonal M)
(if (null? M)
'()
(cons (caar M)
(diagonal (map cdr (cdr M))))))
It's going to take basically the same amount of operations in terms of building the diagonal, but the second one doesn't require a new list be generated up front and doesn't require determining the size of the matrix, so it's a little better.