Haskell: Using map in function composition

dictionary, function-composition, haskell, syntax

Solution

Recall the type of `(.)`.

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

It takes three arguments: two functions and an initial value, and returns the result of the two functions composed.

Now, application of a function to its arguments binds tighter than the `(.)` operator. So your expression:

map (*2) . filter even [1,2,3,4]

is parsed as:

(.) (map (*2)) (filter even [1,2,3,4])

now, the first argument, `map (*2)` is ok. It has type `(b -> c)`, where `b` and `c` is `Num a => [a]`. However, the second argument is a single list:

Prelude> :t filter even [1,2,3,4]
filter even [1,2,3,4] :: Integral a => [a]

and so the type checker will complain that you're passing a `[a]` as an argument when the `(.)` function needs a function.

And that's what we see:

Couldn't match expected type `a0 -> [b0]' with actual type `[a1]'
In the return type of a call of `filter'
In the second argument of `(.)', namely `filter even [1, 2, 3, 4]'
In the expression: map (* 2) . filter even [1, 2, 3, 4]

So... parenthesization!

Either use the `$` operator to add a parenthesis:

map (*2) . filter even $ [1,2,3,4]

or use explicit parens, removing the composition of two functions

map (*2) (filter even [1,2,3,4])

or even:

(map (*2) . filter even) [1,2,3,4]

Problem

I am relatively new to Haskell so apologies if my question sounds stupid. I have been trying to understand how function composition works and I have come across a problem that I was wondering someone could help me with. I am using map in a function composition in the following two scenarios: - `map (*2) . filter even [1,2,3,4]` - `map (*2) . zipWith max [1,2] [4,5]` Although both the filter and zipWith functions return a list, only the first composition works while the second composition throws the below error: ``` "Couldn't match expected type '[Int] -> [Int]' with actual type '[c0]' ``` Any suggestions would be greatly appreciated.

Original source

Related problems