# Mapping

If you’ve used only one of Python’s iterator functions, there’s a good chance it’s this one. `map` in Python

`map` is essential because it’s the functor operation for lists: The notion of a functor is a small thing, but it provides a surprising depth of useful ideas to think about. We go into functors in depth in Functortown: A Map of the Territory. It operates over the content of the list but not the structure of the list. This implies, among other things, that the list that `map` returns will always have the same number of elements as the input list.

## `map`

``````>>> xs = [1, 2, 3]

>>> it = map(lambda x: x * 10, xs)

>>> list(it)
[10, 20, 30]``````

This function has the same name in Haskell. `map` in `Data.List` and `Prelude`

``````λ> xs = [1, 2, 3]

λ> map (\x -> x * 10) xs
[10,20,30]``````

You often see `map` written in Haskell in its more polymorphic form, `fmap`. `fmap` in `Data.Functor` and `Prelude` This is a function that works on any type that has a `Functor` instance. For lists, it specializes to `map`. So this is the same as the previous example:

``````λ> fmap (\x -> x * 10) xs
[10,20,30]``````

There is also an infix version of `fmap`, called `(<\$>)`. So we could also write this example as:

``````λ> (\x -> x * 10) <\$> xs
[10,20,30]``````

Whether you use `fmap` or `(<\$>)` is up to you – sometimes one or the other will be more convenient or clear in a particular context, but often it’s just a matter of personal preference.

## With more than one iterator

When `map` is applied to a binary function and two list arguments, it does something a bit more: It steps through both lists in tandem, applying the function to one element from each of the lists.

``````>>> it = map(operator.add, [1, 2, 3], [10, 100, 1000])

>>> list(it)
[11, 102, 1003]``````

This notion of iterating through two lists at once is sometimes called zipping. We will discuss zipping more when we get to the `zip` function in the next lesson. Haskell calls this function `zipWith`: `zipWith` in `Data.List` and `Prelude`

``````λ> zipWith (+) [1, 2, 3] [10, 100, 1000]
[11,102,1003]``````

Python’s `map` can be used with any number of arguments. Haskell does not overload like this, but has separate functions `zipWith3`, `zipWith4`, etc. to achieve the same result.

``````zipWith  :: (a -> b -> c)           -> [a] -> [b] -> [c]
zipWith3 :: (a -> b -> c -> d)      -> [a] -> [b] -> [c] -> [d]
zipWith4 :: (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]``````

## `starmap`

`starmap` is like a cross between `map` used with a single iterator and `map` used with multiple iterators. It only takes a single iterator parameter, but the function being mapped doesn’t have to be unary. Each element of the iterator is a tuple containing as many arguments as the function has parameters.

``````>>> it = starmap(pow, [(2,5), (3,2), (10,3)])

>>> list(it)
[32, 9, 1000]``````

In this example the function we mapped (`pow`) has two parameters, and so each element of the iterator is a 2-tuple.

This is called “star map” because This use of `*` in Python is called iterable unpacking. we could have also written it like this:

``````>>> it = map(lambda x: pow(*x), [(2,5), (3,2), (10,3)])

>>> list(it)
[32, 9, 1000]``````

There’s no precise Haskell analogue here because Python generalizes over function arity in a way that Haskell doesn’t. If we wanted to compute exponents over a list of number pairs as the example above does, we’d probably write something like this:

``````λ> map (\(a, b) -> a ^ b) [(2,5), (3,2), (10,3)]
[32,9,1000]``````

For functions of two parameters, Python’s “star” is reminiscent of uncurrying in Haskell. `uncurry` in `Data.Tuple` and `Prelude` If we wrote a function similar to `starmap`, we might call it `uncurrymap`:

``uncurrymap = map . uncurry``

For a function of two parameters, we can use this just like `starmap`.

``````λ> uncurrymap (^) [(2,5), (3,2), (10,3)]
[32,9,1000]``````

We mention `uncurry` here mostly as a curiosity. It does not appear often in Haskell code, and the first version using `map` and a lambda expression is the more common way to write this expression.

Join Type Classes for courses and projects to get you started and make you an expert in FP with Haskell.