kxk
kxk

Reputation: 596

Haskell: Taking a list of lists and breaking them down to several single lists (not concatenate)

this is a really basic question I know, I am a begginer in Haskell. So, I am wondering how to "take" the lists from a function like:

putStr( f [[1,2,3],[4,5,6],[6,7,8]])

I don't know if I am expressing this correctly, but I want to create a function f that takes this type:

type Matrix a = [[a]]
type IntMat = Matrix Integer

and then does some things on each "row" of the matrix, nameley the inner lists.

The thing is, I am not quite sure as to how to address them! :S If I am not making ANY sense at all, please ask me to explain!

Thank you in advance!

Upvotes: 2

Views: 6104

Answers (5)

user395760
user395760

Reputation:

Let f :: [Int] -> a be the function that does want you want to do to each row of the IntMat.

Then you can apply it to each row of the matrix by using map: putStr $ map f [[1,2,3],[4,5,6],[6,7,8]] passes each element of the list to f and returns a a new list, where the first element is the result of f firstElement, the second element is the result of f secondElement, etc. Map is defined as

map :: (a -> b) -> [a] -> [b]
map f []     = []
map f (x:xs) = f x : map f xs

For example, to increment each element:

incElem :: Int -> Int
incElem x = x + 1

incRow :: [Int] -> [Int]
incRow row = map incElem row

incMat :: IntMat -> IntMat
incMat mat = map incRow mat

(Note that this would usually be written much more succinctly like incMat = map . map $ (+1) - you don't have to understand how this one works when you're starting out, it's just FYI)

Of course the result of f doesn't have to be a list. If it's type is [Int] -> String, then map f is [[Int]] -> [String]. Argument and result have to be a list, of course.

Upvotes: 1

John
John

Reputation: 138

I think you want (map . map). If I understand you correctly, you want to perform some operation on each element of the sublists and return a new list.

First, lets look at what (map . map) is:

Prelude> :t (map . map)
(map . map) :: (a -> b) -> [[a]] -> [[b]]

I think this is pretty self-explanatory.

Lets use it in an example:

Prelude> (map . map) (+1) [[1..3],[4..7],[8..10]]
[[2,3,4],[5,6,7,8],[9,10,11]]

So, in this case, we're applying the function (+1) to each element of the sublists and returning a new list with the same 'shape' as the old one, but with updated elements.


Edit: I misunderstood. This operates on the inner-most elements of the nested list, not the nested lists themselves.

Upvotes: 1

luqui
luqui

Reputation: 60533

The function you are looking for is map. Eg.:

>>> map maximum [[1,2,3],[4,5,6],[6,7,8]]
[3,6,8]

Upvotes: 0

kennytm
kennytm

Reputation: 523734

"find the max of each of the inner lists", "find their length to use later on", both of them can be done with the map higher-order function.

Prelude> let a = [[1,2,3],[4,5,6],[6,7,8]] :: [[Integer]]
Prelude> map maximum a
[3,6,8]
Prelude> map length a
[3,3,3]

If you have a list M = [a, b, c, d, ...], and you want to use a function f to transform the list into N = [f(a), f(b), f(c), f(d), ...], then you could use the function map (N == map f M).

Upvotes: 5

Yuras
Yuras

Reputation: 13876

If you want to take ith row, then you can use the (!) operator.

Prelude> [[1, 2], [3]] !! 1
[3]
Prelude> [[1, 2], [3]] !! 0
[1,2]
Prelude> 

If you want to apply any function to every row, then you can use map

Prelude> map length[[1, 2], [3]]
[2,1]

Upvotes: 0

Related Questions