为什么要在涉及方法应用的连续参数中加上括号? [英] Why should successive arguments involving method application be parenthesized?
问题描述
假设以下F#函数:
let f (x:int) (y:int) = 42
我怀疑我需要在下面的示例z2中加括号的原因是由于类型推断;我的例子可能不是很好,但是很容易想象事情会变得很毛茸茸:
I suspect that the reason I need to parenthesize the arguments in example z2 below is because of type inference; my example might not be great, but it's easy to imagine how things could get very hairy:
let z1 = f 2 3
let z2 = f 2 (f 3 5)
但是,以下情况我不太清楚:
However, the following case is less clear to me:
let rng = System.Random()
let z3 = f 1 rng.Next(5)
z3无法正常工作,并显示明确的错误消息:
z3 doesn't work, with a clear error message:
错误FS0597:后续参数应该用空格或 元组,以及涉及函数或方法应用程序的参数 加上括号.
error FS0597: Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized.
修复起来很琐碎(将所有内容括起来),但是我不清楚的是为什么这样的表达式是一个问题.我认为这再次与类型推断有关,但是在我看来,天真地是,在此方法中,用括号括起来的参数列表实际上会使事情变得不太可能含糊不清.这是否与rng.Next(5)
等同于rng.Next 5
的事实有关?
Fixing it is trivial (parenthesize all the things), but what I am not clear about is why such an expression is a problem. I assume this has to do with type inference again, but naively, it seems to me that here, methods having a list of arguments surrounded by a parenthesis would actually make things less potentially ambiguous. Does this have to do with the fact that rng.Next(5)
is equivalent to rng.Next 5
?
有人可以提示,给出示例或解释为什么需要此规则,或者如果不存在该规则会出现什么类型的问题?
Can someone hint, give an example or explain why this rule is needed, or what type of problems would arise if it were not there?
推荐答案
我认为这里的问题是代码可以被视为:
I think that the problem here is that the code could be treated as:
let z3 = f 1 rng.Next (5)
这等效于省略括号,因此它将使用3个参数(第二个是函数值)调用f
.这听起来有些愚蠢,但是编译器实际上并不严格要求在参数之间留有空格.例如:
This would be equivalent to omitting the parentheses and so it would be calling f
with 3 arguments (the second being a function value). This sounds a bit silly, but the compiler actually does not strictly insist on having a space between parameters. For example:
let second a b = b
add 5(1) // This works fine and calls 'add 5 1'
add id(1) // error FS0597
add rng.Next(5) // error FS0597
add (rng.Next(5)) // This works fine (partial application)
我认为问题在于,如果您看一下上面片段中的4个示例的顺序,则不清楚在第二种情况和第三种情况下应该获得哪种行为.
I think the problem is that if you look at the sequence of the 4 examples in the above snippet, it is not clear which behavior should you get in the second and the third case.
仍然以特殊方式处理呼叫rng.Next(5)
,因为如果由单参数应用程序形成的呼叫没有空间,则F#允许您将其链接起来.例如rng.Next(5).ToString()
.但是,例如,允许写second(1)(2)
,但是second(1)(2).ToString()
将不起作用.
The call rng.Next(5)
is still treated in a special way, because F# allows you to chain calls if they are formed by single-parameter application without space. For example rng.Next(5).ToString()
. But, for example, writing second(1)(2)
is allowed, but second(1)(2).ToString()
will not work.
这篇关于为什么要在涉及方法应用的连续参数中加上括号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!