
This is why I found it so surprising - and annoying - that you can't use a 2-argument function in a point-free expression.
For example, "zipWith (*)" expects two arguments, and yet
sum . zipWith (*)
fails to type-check. You just instead write
\xs ys -> sum $ zipWith(*) xs ys
which works as expected.
Prelude> :t \xs ys->sum $ zipWith (*) xs ys \xs ys->sum $ zipWith (*) xs ys :: (Num a) => [a] -> [a] -> a Prelude> :t \xs->sum . zipWith (*) xs \xs->sum . zipWith (*) xs :: (Num a) => [a] -> [a] -> a Prelude> :t (sum .) . zipWith (*) (sum .) . zipWith (*) :: (Num a) => [a] -> [a] -> a Prelude> :t (\g->sum . g) . zipWith (*) (\g->sum . g) . zipWith (*) :: (Num a) => [a] -> [a] -> a (.) composes single-parameter functions, so in (f . g) x y, g only gets the first parameter, x. but by adding further levels of composition to f, we can let g consume more parameters. claus