
On Fri, 2008-07-25 at 22:45 +0300, Anatoly Vorobey wrote:
2. I initially tried
where sumIt = sum $ map read
(the "point-free" style, I believe it's called?) but that didn't compile. Why not? A friend suggested
where sumIt = sum . map read
and that does work; I guess my real problem, then, is that I don't really understand the difference between the two and why the former doesn't work.
The $ is an operator that performs function application. So for example: show $ "Hello" is equivalent to show "Hello" You don't need an operator for function application, normally you just type your arguments after the function. But $ just happens to be right-associative, which means it will "evaluate" (modulo lazy semantics of course) its right-hand-side argument before applying it to its left-hand-side argument. So your expression sum $ map read First "evaluates" (map read) then applies it to sum. That is, it's the same as: sum (map read) This is a type error, as the compiler will tell you. The function composition operator (.) takes two functions f :: (b->c) and g :: (a->b) and returns a function (a->c) that effectively first applies g (yielding a 'b') and then f (yielding a 'c'). That is: f after g. So: sum . map read which should be read as: sum . (map read) which is equivalent to: (\x -> sum ((map read) x)) which is itself a new function that reads a list of strings and sums the result. In my opinion it's often helpful to look at the function types using :t in ghci, e.g. ":t (.)" and ":t ($)" (don't forget the brackets around the operators). I'm not an experienced Haskell programmer myself but I'd suggest not using point free style if you find it confusing, but rather write out parameter names and lambdas explicitly. You style will change as you get more comfortable with the language. Regards, Niels