- A+

I tried to find the type of the function `(.) map`

but somehow find that it is `((a -> d) -> (a -> e)) -> ([d] -> [e])`

which according to GHCI is not correct because it should be `(.) map :: (a1 -> a2 -> b) -> a1 -> [a2] -> [b]`

.

What am I doing wrong?

# Deriving the type...

We have as ingredients:

`(.) :: (b -> c) -> (a -> b) -> a -> c map :: (d -> e) -> [d] -> [e] `

(here I used different type identifiers for the two functions to avoid any confusion). A more verbose form (where we make it more explicit that every function takes exactly *one* parameter) is:

`(.) :: (b -> c) -> ((a -> b) -> (a -> c)) map :: (d -> e) -> ([d] -> [e]) `

Since `map`

is the first parameter of `(.)`

that means that its type `(d -> e) -> ([d] -> [e])`

should match the input type of the `(.)`

function (so `b -> c`

). This thus means:

` b -> c ~ (d -> e) -> ([d] -> [e]) ------------------------------ b ~ (d -> e), c ~ ([d] -> [e]) `

So that means that the result type of `(.) map`

is:

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

which is equivalent to:

`(a -> (d -> e)) -> (a -> ([d] -> [e])) `

or less verbose:

`(.) map :: (a -> d -> e) -> a -> [d] -> [e] `

# ... and its implementation

The `(.)`

function can be seen as `(.) f g == /x -> f (g x)`

. So that means that our function

`h = (.) map `

is equivalent to:

`h f x = map (f x) `

It thus takes as input a function `f`

and an object `x`

, and than performs a `map`

with `f x`

as function.

Semancially you could say that we make a "*map where one has to inject a 'contect'-objecct*" of type `a`

. This context is then taken into account by the processor. This could be useful if we want to apply multiple `map`

s, each with a small change, and thus first pass a "context-object". This is of course *an* interpretation of humans. For a compiler, the `x`

can have any use, interpretation, etc.