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.