on

# type tetris

Time for some Haskell. The following expression evaluates to `Just 6`

:

```
fmap sum $ Just [1, 2, 3]
```

So does this one:

```
(fmap . fmap) sum Just $ [1, 2, 3]
```

How does the second one work? How do the type signatures line up?

First consider `fmap . fmap`

:

```
(.) :: (b -> c) -> (a -> b) -> a -> c
fmap :: Functor f => (a -> b) -> (f a -> f b)
(.) fmap :: Functor f => (a1 -> (a -> b))
-> a1
-> (f a -> f b)
fmap . fmap :: (Functor f, Functor f1) => (a -> b)
-> f1 (f a)
-> f1 (f b)
```

Then `sum`

:

```
sum :: (Num a, Foldable t) => t a -> a
```

Now apply `fmap . fmap`

to `sum`

:

```
(fmap . fmap) sum :: (Num b,
Foldable t,
Functor f,
Functor f1) => f1 (f (t b))
-> f1 (f b)
```

Next, the tricky bit.
Note that `(a -> b) ~ ((->) a b)`

.
So the signature of `Just`

, which we’d usually write:

```
Just :: a -> Maybe a
```

can also be expressed as:

```
Just :: (->) a (Maybe a)
```

We want the type signature for `(fmap . fmap) sum Just`

.

Consider the signature of `(fmap . fmap) sum`

.

```
...
Functor f,
Functor f1) => f1 (f (t b))
-> f1 (f b)
```

`f1`

must have a Functor instance.

`((->) a)`

has a Functor instance for all `a`

.

`((->) (t b))`

, therefore, has a Functor instance.

If we replace `f1`

with `((->) (t b))`

, we produce a more specific type signature, expressing a specialization of `(fmap . fmap) sum`

```
... => ((->) (t b)) (f (t b))
-> ((->) (t b)) (f b)
```

We can further specialize it by replacing `f`

with Maybe.

```
... => ((->) (t b)) (Maybe (t b))
-> ((->) (t b)) (Maybe b)
```

Now consider a specialization of `Just`

where `a ~ (t b)`

```
Just :: (->) (t b) (Maybe (t b))
```

If we apply the specialized `(fmap . fmap) sum`

to this specialization of `Just`

, we get:

```
... => ((->) (t b)) (Maybe b)
```

which can be rewritten idiomatically as:

```
... => t b -> Maybe b
```

This leaves us with:

```
(fmap . fmap) sum Just :: (Num b, Foldable t) => t b -> Maybe b
```