Kim-Ee Yeoh ky3 at atamo.com
Tue Apr 8 05:54:17 UTC 2014

```John,

This is one MAJOR hurdle for newcomers to get over and pretty much everyone
stumbles and falls into typed combinator enlightenment. Eventually.

Let's ask ghci what some of the types are:

:t [1,2,3]
[1,2,3] :: [Int]

:t (+7)
(+7) :: Int -> Int

:t (<\$>)
(<\$>) :: Functor f => (a -> b) -> f a -> f b

So in ((+7) <\$>) we have

(<\$>) :: Functor f => (a -> b) -> f a -> f b

applied to (note the _type_ of the first argument: a -> b):

(+7) :: Int -> Int

Now the type variables a and b must match up, so we have a=b=Int.

And now we have

((+7) <\$>) :: Functor f => f Int - f Int

Which is, in turn, applied to

[1,2,3] :: [Int]

The argument in ((+7) <\$>) has type Functor f => f Int, whereas [1,2,3] is
[Int], so what can f be?

Answer: []. Yes, [] is a functor, the way Maybe and IO are functors. So f =
[]. It's unusual but only syntatically in the sense that Haskell says to
write Maybe Int but rejects [] Int. You have to write [Int] to mean [] Int.

We say that

((+7) <\$>) :: Functor f => f Int - f Int

is thus specialized to

((+7) <\$>) :: [Int] -> [Int]

which is why (+7) <\$> [1,2,3] typechecks and runs as it should.

If you run through the above against the rest of the list of things that do
and don't work, I think you'll sew up typed combinators as a fine feather
in your cap. Just remember that [] is a Functor and also an Applicative and