There are a number of cases in the `base`

package where the same
functionality exists under two different names. This can occur for a
number of different reasons, but most commonly it's either:

- One version is more general than the other via some typeclass
- A historical name has lingered on

The presence of identical (or nearly identical) functionality under different names can lead to confusion when reading code. The purpose of this page is to point out these occurrences to bypass this confusion.

```
GHC.OldList.concat :: [[a]] -> [a]
Prelude.concat :: Foldable t => t [a] -> [a]
mconcat :: Monoid a => [a] -> a
fold :: (Foldable t, Monoid a) => t a -> a
```

All four of these functions allow us to collapse down a sequence of
values into a single value. The most specific is `GHC.OldList.concat`

:
given a list of lists, it combines all of these lists together into a
single list. The most general is `fold`

, which leverages two
typeclasses:

- Instead of requiring that the containers be a list, it leverages the
`Foldable`

typeclass to work with many more data structures - Instead of requiring that the values being combined be lists, it
generalizes to any instance of
`Monoid`

```
GHC.OldList.concatMap :: (a -> [b]) -> [a] -> [b]
Prelude.concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b
```

This is very similar to the `concat`

/`mconcat`

/`fold`

breakdown
above. We can generalize from lists to instances of `Foldable`

and
`Monoid`

.

```
(*>) :: Applicative f => f a -> f b -> f b
(>>) :: Monad m => m a -> m b -> m b
```

The only difference between these two is `Applicative`

vs
`Monad`

. This is a holdover from the days when `Applicative`

was not a
superclass of `Monad`

.

```
pure :: Applicative f => a -> f a
return :: Monad m => a -> m a
```

`return`

is `pure`

specialized to `Monad`

, relevant for the same
superclass reason above.

```
map :: (a -> b) -> [a] -> [b]
fmap :: Functor f => (a -> b) -> f a -> f b
liftM :: (Monad m) => (a -> b) -> m a -> m b
```

`map`

is specialized to just lists, while `fmap`

is generalized to all
`Functor`

s. Like `*>`

vs `>>`

, the presence of `liftM`

is just a
holdover from the days when `Functor`

was not a superclass of `Monad`

.

```
traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
```

`mapM_`

is `traverse_`

specialized to `Monad`

, relevant for the same
superclass reason above.

```
sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
```

Same `Monad`

/`Applicative`

specialization.

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

Same `Monad`

/`Applicative`

specialization.

```
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
```

Same `Monad`

/`Applicative`

specialization.

```
for :: (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b)
forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
```

Same `Monad`

/`Applicative`

specialization.

```
(++) :: [a] -> [a] -> [a]
Data.Semigroup.(<>) :: Semigroup a => a -> a -> a
mappend :: Monoid m => m -> m -> m
```

`++`

is simply `<>`

and `mappend`

specialized to lists. `mappend`

should be the
same as `<>`

in all cases.

Note: historically, `Semigroup`

was not a superclass of `Monoid`

, resulting in
`<>`

and `mappend`

having potentially different implementations. That no longer
applies.