Re: [Haskell-cafe] Function Precedence

Think about this:
map (+1) [1..10]
What should it do? take (+1) and return a function which takes a list as its argument and finally return a list.
How about:
f 1 2 3
Should that be f (1 (2 3)), or ((f 1) 2) 3? The latter, of course, but that's not really what I'm driving at. I'm asking why we can't have a function treated differently with regard to the precedence and associativity rules. f 1 2 is indeed ((f 1) 2). Why not f 1 g 2 == ((f 1) (g 2))?
Cheers, Paul

PR Stanley wrote:
Should that be f (1 (2 3)), or ((f 1) 2) 3? The latter, of course, but that's not really what I'm driving at. I'm asking why we can't have a function treated differently with regard to the precedence and associativity rules. f 1 2 is indeed ((f 1) 2). Why not f 1 g 2 == ((f 1) (g 2))?
Are you asking why one doesn't change the rules for all functions? Or are you asking why Haskell doesn't include a system of user-defined precedence and associativity for function application so that one could declare that g binds more tightly than f? I see good reasons for both questions, but I'm unsure which you mean. In both cases, it comes down to consistency of the syntax rules. In order for (f 1 g 2) to parse as (f 1) (g 2), one would have to do something surprising. It's unclear what that is: perhaps treat literals differently from variables? Somehow determine a precedence level for (f 1)? Or maybe favor shorter argument lists for grouping function application? If you have a very clear kind of grouping that you think makes sense in all cases, feel free to mention it. It seems unlikely to me, but perhaps everyone will agree, once they see it, that it is in fact better than the current parsing rules. -- Chris Smith

Are you asking why one doesn't change the rules for all functions? Or are you asking why Haskell doesn't include a system of user-defined precedence and associativity for function application so that one could declare that g binds more tightly than f? I see good reasons for both questions, but I'm unsure which you mean. In both cases, it comes down to consistency of the syntax rules. In order for (f 1 g 2) to parse as (f 1) (g 2), one would have to do something surprising. It's unclear what that is: perhaps treat literals differently from variables? Somehow determine a precedence level for (f 1)? Or maybe favor shorter argument lists for grouping function application? If you have a very clear kind of grouping that you think makes sense in all cases, feel free to mention it. It seems unlikely to me, but perhaps everyone will agree, once they see it, that it is in fact better than the current parsing rules. Paul: All you'd have to do is to give the inner most function the highest precdence therefore f g x == f (g x) let f x = x^2 let g x = x`div`2 f g 4 == error while f (g 4) == 4 I'm beginning to wonder if I fully understand the right associativity rule for the -> operator. Cheers, Paul

On Apr 1, 2008, at 17:07 , PR Stanley wrote:
I'm beginning to wonder if I fully understand the right associativity rule for the -> operator.
Read a parenthesized unit as an argument:
(a -> (b -> (c -> d))) (((f 1) 2) 3) (((a -> b) -> c) -> d) (f (1 (2 3)))
-- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

PR Stanley wrote:
All you'd have to do is to give the inner most function the highest precdence therefore f g x == f (g x) let f x = x^2 let g x = x`div`2 f g 4 == error while f (g 4) == 4
I'm afraid I still don't understand what you're proposing. How can f g x mean f (g x), and yet f g 4 is different from f (g 4)? Maybe it'll help to point out that using functions as first-class concepts -- including passing them around as data -- is fundamental to functional programming languages. In other words, anything in the world could be a function, whether it's acting like a function right now or not. So distinguishing between (f g 4) and (f 1 2) is probably not wise. They either need to both parse like ((f g) 4), or they need to both parse like (f (1 2)). It has been the experience of the Haskell, ML, and other related languages that left associativity for function application works best.
I'm beginning to wonder if I fully understand the right associativity rule for the -> operator.
It just means that if I have a string of things separated by ->, I can put parentheses around all but the leftmost one, and it doesn't change the meaning. -- Chris Smith

On Tue, Apr 1, 2008 at 2:07 PM, PR Stanley
All you'd have to do is to give the inner most function the highest precdence
What's the innermost function in "f g x" here? test :: (a -> b -> c) -> a -> b -> c test f g x = f g x -- Dan

2008/4/2, Dan Piponi
On Tue, Apr 1, 2008 at 2:07 PM, PR Stanley
wrote: All you'd have to do is to give the inner most function the highest precdence
What's the innermost function in "f g x" here?
test :: (a -> b -> c) -> a -> b -> c test f g x = f g x
g (if I followed correctly). But we have a problem: If I want f g x to be parsed as f (g x), I would probably want, f g x y to be parsed as f (g x y), considering g as the innermost function, again. I'm almost certain that it would render type inference impossible, and maybe partial application as well. (id 4 is a total application, but id (\x -> x+1) is a partial one...) The only choices left are right associativity or left associativity. Loup
participants (5)
-
Brandon S. Allbery KF8NH
-
Chris Smith
-
Dan Piponi
-
Loup Vaillant
-
PR Stanley