Question: So this question is simple but I can't seem to grasp the concept.

To compose ordinary functions, one can just do something like below:

```
lowerNoSpaces = filter (/= ' ') . map toLower

```

But, on occasion, there are times where this won't work:

```
myConcatMap = concat . map

```

It gives the error:

```
<interactive>:236:1: error:
    * Non type-variable argument
        in the constraint: Foldable ((->) [a1])
      (Use FlexibleContexts to permit this)
    * When checking the inferred type
        concattMap :: forall a1 a2.
                      Foldable ((->) [a1]) =>
                      (a1 -> a2) -> [a2]

```

But when the same function is expressed like this:

```
myConcatMap = (concat .) . map

```

It works exactly as intended.

I know there is a reason for this, but I have been staring at it for a while and still don't quite understand why the original doesn't work and this one does.

Why is there two "." 's?

Answer: 
It's because `map` is a two-argument function, and you want to apply `concat` only after both arguments have been supplied. Keep in mind that Haskell multi-argument functions are curried, i.e. it's actually

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

```

Thus, if you write a composition `c . map`, the argument of `c` must be something of type `[a]->[b]`. But the argument of `concat` is supposed to be a list, i.e. something of type `[b]` or actually `[[e]]`.

Solutions:

* Pass the first argument explicitly.

```
myConcatMap f = concat . map f

```

This works because `map f` is only a one-argument function anymore `[a] -> [b]`, thus you can compose `concat` in front of it.
* Compose `concat` in front of the function *that's the result of applying `map` to its first argument*. That's what you're doing in your example.
Let's look at some type signatures.

```
concat :: Foldable t => t [a] -> [a]
map :: (a -> b) -> [a] -> [b]
(.) :: (b -> c) -> (a -> b) -> a -> c

```

Now, does `concat . map` make sense? For simplicity, let's assume that `Foldable` member is just lists.

The first argument to `(.)` is `concat`, of type `[[d]] -> [d]` (to avoid name collisions). Substituting that for `(b -> c)` gives us:

```
(.) concat :: (a -> [[d]]) -> a -> [d]

```

Try applying that to `map`. Applied to a single argument, `map` gives you a function; this does not match the `[[d]]` that `(.) concat` expects of its first argument. We've got ourselves an issue.

But what if you supply `map` with a single argument first? `map g` has signature `[e] -> [f]`, so we end up with this type signature:

```
(.) concat (map g) :: [e] -> f

```

That typechecks, so we've got something meaningful here! If you'll notice, we're first applying `map` to `g`, then applying `(.) concat` (equivalently `(concat .)`) to that result, so that function can be rewritten like so:

```
(concat .) . map $ g

```

This form allows us to get rid of the `g` entirely and put your function `myConcatMap` into pointfree form:

```
myConcatMap = (concat .) . map

```