> Date: Tue, 6 Mar 2007 14:43:03 -0500
> From: Jefferson Heard <jeff@renci.org>
>
> Usually, I can do this, but today, my brain is weak, and I'm just trying to
> get this piece of code out the door.  My code looks like this:
>
> weight = sum (IntMap.elems (IntMap.intersectionWith
>                      (\x y -> x*y) queryVector rationalProjection))
>
> I know that this will work (ignoring indentation):
>
> sum $ IntMap.elems $ IntMap.intersectionWith (\x y -> x*y) queryVector
> rationalProjection
>
> But why won't this?:
>
> sum . IntMap.elems . IntMap.IntersectionWith ...

(.) is for function composition - both of its arguments must be functions, and of compatible types

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

IntMap.intersectionWith (\x y -> x*y) queryVector rationalProjection

has a type which is not a function (sorry, I don't have IntMap handy, so I can't reliably be more specific - I'm guessing the type is something like IntMap a).

You can compose a whole string of functions a . b . c . d, but if you want to end up with a value, as here, then you eventually need to apply the resulting function to a value, which is where ($) comes in.  When you're using (.) and ($) to build a complex expression, there's several possible combinations that will work, but assuming you're calculating a value rather than just building a complex function, there will be one or more ($)s towards the right of the expression, and zero or more (.)s towards the left.

(I'm sure somebody could come up with a more complex example where this doesn't hold, but this describes the typical function-pipeline case.)

> Is there a difference between the "elegance" of function composition versus
> application?

There's certainly a school of thought that considers it better style to compose all your functions and then apply them to your argument, which I have some sympathy with.  I can also see circumstances where there may be practical advantages to using application throughout - it may make it easier to edit the pipeline if it uses application consistently.
--
Iain Alexander      ia@stryx.demon.co.uk