Recently, a a good friend of mine has been explaining to me how powerful the `traverse`

function is in Haskell. The main point being that it's a generalization of both `map`

and `fold`

.

For those who are unfamiliar, `traverse`

has the following function definition:

```
traverse
:: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
```

At first glance, it was *very* unclear to me how one could obtain the features of `fold`

within traverse. Things only started to click after I digested the following line:

To get fold, choose an applicative that “accumulates” the result you want

In other words, we can get `fold`

for free simply by choosing our desired applicative to wrap `b`

in.

Lets say we have a list of numbers, and we would like to ensure that all the numbers in the list are all `Just`

even numbers, or `Nothing`

.

Without using `traverse`

could do it like so:

```
myData = [1,2,3,4,5]
isEven x = x `rem` 2 == 0
myResult = do
let filtered = filter isEven myData
if length filtered == length myData
then Just filtered
else Nothing
```

It *works*, however we can make it more succinct simply by using `traverse`

.

```
myData = [2,4,6,8]
isEvenF x
| x `rem` 2 == 0 = Just x
| otherwise = Nothing
myResult = traverse isEvenF myData
```

While the previous example was nice and short, it fails to showcase where (in my opinion) `traverse`

excels at - **seperating data handling logic from the data traversing logic**. This is particularly useful in highly nested data structures.

What do I mean by that? Lets say we have a list of numbers. And we would like to sum all the even numbers within the list. Traditionally, we can do it like so:

```
myData = [1,2,3,4,5]
isEven x = x `rem` 2 == 0
myResult = sum $ filter isEven myData
```

But what if we had a nested list?

```
myNestedData = take 6 (repeat myData)
myNestedResult = do
let temp1 = filter isEven <$> myNestedData
let temp2 = sum <$> temp1
sum temp2
```

I'm sure we can refactor this to make it look neater, but things do get a bit messy as our data structures gets more nested / complicated.

Compare that with the `traverse`

approach:

```
import Control.Monad.State.Lazy
myData = [1,2,3,4,5]
addIfEven x
| x `rem` 2 == 0 = (+x)
| otherwise = id
sumIfEven x = do
modify (addIfEven x)
return x
myResult = execState (traverse sumIfEven myData) 0
```

While the initial setup is messier, we can easily compose `traverse`

so we can easily perform the same operation regardless of how nested the underlying data structure is:

```
myNestedData = take 6 (repeat myData)
myResult = execState ((traverse . traverse) sumIfEven myData) 0
```

`traverse`

, like many many haskell concepts are extremely unintuitive on first glance, due to how abstract they are. But as you slowly build up a foundation and intuition on these generalized abstractions, they become very powerful tools in your arsenal.