我主要谈的是函数式编程语言。例如,map的维基百科文章以Haskell-ish语言为例:
map square [1,2,3,4,5]
解析器/编译器如何知道我们想要将函数square
作为高阶函数传递给map
,而不是尝试调用函数本身?对于使用静态类型的语言,表达式square [1,2,3,4,5]
显然不会编译,但编译器是否真的使用它来确定这不是我的意思?
或者,这只是维基百科的一个不好的例子,一个更好的例子可能看起来像map &square [1,2,3,4,5]
(使用C风格的函数引用)?
答案 0 :(得分:5)
首先,功能应用程序具有最高优先级。所以当解析器遇到“map”时,它会将第一个东西作为第一个参数。 map类型需要一个函数作为第一个参数,“square”被定义为一个函数,因此类型是兼容的。您可以将map square视为期望数字列表的函数。
关键是检查类型,并验证参数类型,遵循优先规则。
答案 1 :(得分:4)
这只是一个解析问题:Haskell中的函数应用程序是左关联的,因此map square [1, 2, 3, 4, 5]
被解析为((map square) [1, 2, 3, 4, 5])
而不是(map (square [1, 2, 3, 4, 5]))
。
答案 2 :(得分:0)
这取决于语言。
例如,在Javascript中,您可以通过简单地不在括号后面引用函数f
。
这里,f被视为函数指针。
map(f, [1,2,3,4,5]);
这里,它被视为函数调用:
f([1,2,3,4,5]);
在Scala中,规则相当复杂,编译器在“猜测”您是否正在调用或引用该函数方面有一些余地。有关更详细的说明,请参阅What is the rule for parenthesis in Scala method invocation?。