
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 there a difference between the "elegance" of function composition versus application?

haskell-cafe-bounces@haskell.org wrote on 03/06/2007 02:43:03 PM:
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 there a difference between the "elegance" of function composition versus application?
I assume your really asking why something like: (*) $ 2 $ 3 won't work? If so, the reason is that $ associates to the right. So you should write: ((*) $ 2) $ 3 If not, could you give the full expression which doesn't work? -Jeff --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.

Nope, I'm asking why um . IntMap.elems . IntMap.IntersectionWith (\x y -> x*y) queryVector rationalProjection won't work. On Tuesday 06 March 2007 15:14, Jeff Polakow wrote:
haskell-cafe-bounces@haskell.org wrote on 03/06/2007 02:43:03 PM:
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 there a difference between the "elegance" of function composition
versus
application?
I assume your really asking why something like:
(*) $ 2 $ 3
won't work? If so, the reason is that $ associates to the right. So you should write:
((*) $ 2) $ 3
If not, could you give the full expression which doesn't work?
-Jeff
---
This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.

Jefferson Heard
Nope, I'm asking why
um . IntMap.elems . IntMap.IntersectionWith (\x y -> x*y) queryVector rationalProjection
won't work.
We have (simplifying away some typeclass details): sum . elems :: IntMap a -> a and: intersectionWith (*) :: IntMap a -> IntMap a -> IntMap a but: ((sum . elems) .) :: (IntMap a -> IntMap a) -> IntMap a -> a so you need something like: sum . elems . uncurry (intersectionWith (*)) $ (queryVector, rationalProjection) -Jeff --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.

sum . IntMap.elems . IntMap.IntersectionWith (\x y -> x*y) queryVector rationalProjection
Composition with (.) builds a function, but you eventually want an Int, so we can't just use (.), but we can come pretty close. (sum . IntMap.elems . IntMap.IntersectionWith (\x y -> x*y) queryVector) rationalProjection

On 06/03/07, Nicolas Frisby
Composition with (.) builds a function, but you eventually want an Int, so we can't just use (.), but we can come pretty close.
(sum . IntMap.elems . IntMap.IntersectionWith (\x y -> x*y) queryVector) rationalProjection
Often written: f . g . h $ x This is often prefered to the alternative: f $ g $ h $ x As it's visually lighter, and involves less editing if you wanted to get rid of the x (say, you were eta-reducing the expression). As to why: f . g . h . x doesn't work, (.) can only compose two functions, but x is not a function, it is a value, so you have to apply it to the composite function f . g . h using the ($) operator or parentheses. -- -David House, dmhouse@gmail.com

On Tue, Mar 06, 2007 at 10:19:12PM +0000, David House wrote:
On 06/03/07, Nicolas Frisby
wrote: Composition with (.) builds a function, but you eventually want an Int, so we can't just use (.), but we can come pretty close.
(sum . IntMap.elems . IntMap.IntersectionWith (\x y -> x*y) queryVector) rationalProjection
Often written:
f . g . h $ x
Alternativly, (f . g . h) x will work, too.
This is often prefered to the alternative:
f $ g $ h $ x
As it's visually lighter, and involves less editing if you wanted to get rid of the x (say, you were eta-reducing the expression).
As to why:
f . g . h . x
doesn't work, (.) can only compose two functions, but x is not a function, it is a value, so you have to apply it to the composite function f . g . h using the ($) operator or parentheses.
-- -David House, dmhouse@gmail.com _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 3/7/07, mm
f . g . h $ x
Alternativly,
(f . g . h) x
will work, too.
It always irks me that you don't actually save any horizontal space using $. That is, (e) x has the same number of characters (incl spaces) as e $ x T. -- Dr Thomas Conway You are beautiful; but learn to work, drtomc@gmail.com for you cannot eat your beauty. -- Congo proverb

On 7 Mar 2007, at 09:44, Thomas Conway wrote:
On 3/7/07, mm
wrote: f . g . h $ x
Alternativly,
(f . g . h) x
will work, too.
It always irks me that you don't actually save any horizontal space using $. That is, (e) x has the same number of characters (incl spaces) as e $ x
I have to admit that I often use this form, rather than bracketing. My logic is not that it saves space (as you have demonstrated it doesn't), but instead that it makes my code easier to read and brackets easier to match -- I'd rather have the additional dollar signs than the additional brackets to count. Bob

On Wed, 7 Mar 2007 20:44:42 +1100, you wrote:
It always irks me that you don't actually save any horizontal space using $. That is, (e) x has the same number of characters (incl spaces) as e $ x
Parentheses require you to maintain a mental general-purpose push-down stack as you read the code. $, on the other hand, while it also requires you to maintain a sort of stack, it's a "monotonic" stack: you may need to push an arbitrary number of items, but you don't pop anything until you reach the end of the code. So the mental model required to read code containing $'s is simpler than that required for parentheses. Steve Schafer Fenestra Technologies Corp. http://www.fenestra.com/

Quoth Steve Schafer, nevermore,
Parentheses require you to maintain a mental general-purpose push-down stack as you read the code. $, on the other hand, while it also requires you to maintain a sort of stack, it's a "monotonic" stack: you may need to push an arbitrary number of items, but you don't pop anything until you reach the end of the code. So the mental model required to read code containing $'s is simpler than that required for parentheses.
Which is the longer way of saying you don't need to count to make sure you closed all the brackets you opened! ;-) D. -- Dougal Stanton

Which is the longer way of saying you don't need to count to make sure you closed all the brackets you opened! ;-)
< Dougal Stanton 1) Emacs does the counting for me 2) parens don't surprise me if I happen to use rank-2 types. i was bit enough times when learning why $ and runST don't like each other that I've grown averse of $. I also like thinking of building a composite function instead of sequencing applications--this has helped me see patterns in other places like writing monad transformer instances and other stuff, so maybe it's a good thing. My 2 cents.

On 07/03/07, Nicolas Frisby
1) Emacs does the counting for me 2) parens don't surprise me if I happen to use rank-2 types.
i was bit enough times when learning why $ and runST don't like each other that I've grown averse of $. I also like thinking of building a composite function instead of sequencing applications--this has helped me see patterns in other places like writing monad transformer instances and other stuff, so maybe it's a good thing.
I don't use rank-2 types that often and when I do I'm aware of the restriction on ($) and similar hofs. I tend to use ($) only when the right-hand side gets very messy; a multiple-line do or similar. For example: blah = fromMaybe $ do x <- blah1 y <- blah2 guard (x == f y) g x The closing parenthesis would make things a little messy, so ($) is nice. -- -David House, dmhouse@gmail.com

I don't use rank-2 types that often and when I do I'm aware of the restriction on ($) and similar hofs. I tend to use ($) only when the right-hand side gets very messy; a multiple-line do or similar. For example:
blah = fromMaybe $ do x <- blah1 y <- blah2 guard (x == f y) g x
The closing parenthesis would make things a little messy, so ($) is nice.
-David House, dmhouse@gmail.com
For this situation, I go ahead and name the subcomputation with a where clause or a do-let binding. Usually, naming sub terms can't hurt. Other than "look at Darcs or GHC", has there been any efforts for (very general, libertarian even) coding guidelines? "Suggestions & tips" might be a better word.

Quoth Nicolas Frisby, nevermore:
Other than "look at Darcs or GHC", has there been any efforts for (very general, libertarian even) coding guidelines? "Suggestions & tips" might be a better word.
I think the unwritten word so far has been "if you wouldn't hang it on a wall in the Tate Modern then it's not pretty enough". ;-) I am continually astounded by the beauty on show in tutorials and blog posts. Some stuff's just so elegant it *hurts*. But to answer your question, I think I saw some guidelines on haskell.org at one point. It might even have been on the old wiki. (..checks..) Aha, here we go: http://www.haskell.org/haskellwiki/Programming_guidelines D. -- Dougal Stanton
participants (10)
-
David House
-
Dougal Stanton
-
Iain Alexander
-
Jeff Polakow
-
Jefferson Heard
-
mm
-
Nicolas Frisby
-
Steve Schafer
-
Thomas Conway
-
Thomas Davie