I don’t know other guys, but for me, sometimes I am confused with `$`

(“application operator”) and `.`

(“function composition”) in `Haskell`

, so I want to write a small summary to differentiate them.

Check the type of these two operators:

```
> :t ($)
($) :: (a -> b) -> a -> b
> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
```

For infix operator, `$`

, its left operand should be a function whose type is `a->b`

, the right operand should be the input parameter of this function: `a`

, then get the result `b`

. Check following example:

```
countWords :: String -> Int
countWords s = length $ words s
```

`words`

returns a `String`

list which is the input argument of `length`

, then `length`

returns how many words this string has. Run `countWords`

in `ghci`

:

```
> let countWords s = length $ words s
> countWords "a b c"
3
```

See `.`

now; maybe another the type notation of `.`

can give you a hand in comprehending it:

```
(.) :: (b -> c) -> (a -> b) -> (a -> c)
```

We can think the operands of `.`

are both functions, and the return value is also a function. however, the three functions are not random, but have relationships with their parameters. Modify `countWords`

and run it in `ghci`

:

```
> let countWords s = length . words s
<interactive>:12:29: error:
* Couldn't match expected type `a -> [a0]'
with actual type `[String]'
* Possible cause: `words' is applied to too many arguments
In the second argument of `(.)', namely `words s'
In the expression: length . words s
In an equation for `countWords': countWords s = length . words s
* Relevant bindings include
countWords :: String -> a -> Int (bound at <interactive>:12:5)
```

Woops! Error is generated. The reason is the space ” “, or function application has the highest precedence, so `words s`

should be evaluated first:

```
:t words
words :: String -> [String]
```

The return value is `[String]`

, not a function, so it doesn’t satisfy the type of `.`

who requires the two operands must be functions. Change the `countWords`

definition:

```
> let countWords s = (length . words) s
> countWords "a b c"
3
```

This time it works like a charm! For the same reason, the second operand of `$`

must be consistent with the input parameter of the first operand:

```
> let countWords = length $ words
<interactive>:18:18: error:
* No instance for (Foldable ((->) String))
arising from a use of `length'
* In the expression: length $ words
In an equation for `countWords': countWords = length $ words
```

It is time to warp it up: the operands of `.`

is function, and we can use `.`

to chain many functions to generate a final one which works as the left operand of `$`

, feed it with one argument and produce the final result. Like this:

```
> length . words $ "1 2 3"
3
```

The same as:

```
> length $ words $ "1 2 3"
3
```