19

I am still a haskell beginner. Can I do a double map in haskell?

For example, if I have a [[Char]] and I want to convert each Char in each [Char] to lower case, is there an easy way to do this rather than something like:

exampleF [] = []
exampleF (x:xs) = (map toLower x) : exampleF xs
Dan Burton
  • 53,238
  • 27
  • 117
  • 198
Shane
  • 2,315
  • 3
  • 21
  • 33
  • Me: "@faq Can haskell do a double map?" Lambdabot: "The answer is: Yes! Haskell can do that!" :) – Dan Burton Jan 05 '12 at 00:45
  • It's useful to note that map itself is defined in the Prelude "tail recursively" with the same structure as this snipped... basically you implemented map without even knowing! ;) As far as Haskell semantics, your way and the accepted answer "do" the same thing (the EXACT same thing, i think), they are just written differently. However, saying "map map" is definitely way more elegant. – parker.sikand Oct 01 '14 at 08:28

2 Answers2

29

In fact, there is a nice pattern here:

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

and so on

luqui
  • 59,485
  • 12
  • 145
  • 204
25

You can think of map f, as transforming a function f :: a -> b into a function on lists map f :: [a] -> [b], so if you want to transform it further into a function on lists of lists, you just need to use map again to get map (map f) :: [[a]] -> [[b]].

In this particular case, that becomes:

exampleF = map (map toLower)
hammar
  • 138,522
  • 17
  • 304
  • 385
  • 5
    `exampleF xss = map (\xs -> map toLower xs) xss` - an alternate way to write it if it makes you feel better. However, the way hammar wrote it is encouraged (since it is eta reduced and, in fact, point free). You'll get used to it, if you aren't already. – Dan Burton Jan 05 '12 at 00:39
  • @DanBurton Please elaborate: why point free is better? – Refael Sheinker Jan 30 '23 at 19:29