tags:

views:

366

answers:

4

If I have a matrix given as a list of rows [[1,2,3],[4,5,6]], I want to return the first column, [1,4]. I'm an absolute beginner in Haskell and I have no idea on even how to deal with nested lists.

+4  A: 

The following code will do the job:

map head [[1,2,3],[4,5,6]]

map is one of the most useful functions in haskell (and other functional programming languages). Given a list [a,b,c,d] and a function f, map f [a,b,c,d] will return the list [f a, f b, f c, f d]. The head function extracts the first element of a list. This is why

map head [[1,2,3],[4,5,6]] ->
[head [1,2,3], head [4,5,6]] ->
[1,4]
Jonas
+4  A: 

More generically:

col :: Int -> [[a]] -> [a]
col n = map (head . drop n)

Keep in mind that this will fail if n is greater than or equal to the length of any of the lists you give it.

Curt Sampson
Equivalently, `col n = map (!! n)`, which I think conveys the intention a little clearer. YMMV.
ephemient
A: 

The following code will do the job:

map head [[1,2,3],[4,5,6]]

To expand on Jonas' answer; map applies a function to each element of a list. The result of "mapping" a function over a list is a new list of a different type.

The input list you have here is of type [[Int]], that means, each element in the list is a list of Ints. So you want a function that takes each of the sublists and returns its first element; That is head.

To sum up, map will take the function head, apply it to each of the sublists so that you will get a new list of type [Int] containing just the head (first element) of each list.

Tom Lokhorst
+2  A: 

The library function to convert a matrix of rows to a matrix of columns is Data.List.transpose. So one way to solve your problem is

import Data.List (transpose)
col = head . transpose

You could also write a function to get any column from the matrix:

colN n matrix = transpose matrix !! n

Disclaimers:

Remember that transpose is expensive if you need to transpose the whole matrix. For just the first column, it should be about the same cost as the other solutions people have given.

Also, transpose is relatively dangerous in complicated code because its result is the same type as its argument: [[a]] -> [[a]]. So it's easy to throw in the wrong number of transposes. (I learned this the hard way.)

Nathan Sanders