Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map a function on the elements of a nested list

Tags:

haskell

This is a trival question.

But what is the standard way to map a function (+1 in this example) on nested list?

map (\x -> map (+1) x) [[1,2,3],[4,5,6]]

I use the above way in my code, but what is a good way to do that? Is there something like a mapNested (+1) [[1,2,3],[4,5,6]] or similar? I used google and hoogle but got too much generic results.

like image 551
mrsteve Avatar asked May 14 '14 16:05

mrsteve


People also ask

How do you access elements in a nested list?

You can access a nested list by negative indexing as well. Negative indexes count backward from the end of the list. So, L[-1] refers to the last item, L[-2] is the second-last, and so on.

How do you reference a nested list?

Use multiple indices to reference items within a nested list. Use the syntax list[n] to access the n th element of list . If the n th of list is another list, use list[n][k] to access the k th element of list[n] . This can be used with any number of nested lists.

What is nested Listt?

A nested list is a list that appears as an element in another list. In this list, the element with index 3 is a nested list. If we print( nested[3] ), we get [10, 20] . To extract an element from the nested list, we can proceed in two steps. First, extract the nested list, then extract the item of interest.

Does map always return a list?

map() always returns a list. See the modify() family for versions that return an object of the same type as the input.


2 Answers

There's a few ways but the most obvious is:

Prelude> map (map (+1)) [[1,2,3],[4,5,6]]
[[2,3,4],[5,6,7]]

This would be the textbook answer.

Maybe you like to do the outer part with a list comprehension?

Prelude> [ map (+1) xs | xs <- [[1,2,3],[4,5,6]] ]
[[2,3,4],[5,6,7]]

Or even the whole thing?

Prelude> [ [ x + 1 | x <- xs ] | xs <- [[1,2,3],[4,5,6]] ]
[[2,3,4],[5,6,7]]
like image 169
Don Stewart Avatar answered Oct 19 '22 18:10

Don Stewart


I don't think it defined anywhere in the standard library, but you can define it as such:

mapNested :: (a -> b) -> [[a]] -> [[b]]
mapNested = map . map

Or to make it more generic (ie. work on other functors than lists):

fmapNested :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
fmapNested = fmap . fmap

Example use:

fmapNested (+1) [Some 1, None, Some 3] -- == [Some 2, None, Some 4]
like image 37
Tarmil Avatar answered Oct 19 '22 20:10

Tarmil