我在努力记住在调用Haskell函数时如何使用括号。我来自C风格的背景,我习惯使用f(comma, separated, args)
语法来调用函数。显然这与(在Haskell中)((((f) comma) separated) args)
相同,但这只是令人困惑。
为什么我需要所有这些括号?
答案 0 :(得分:5)
很容易记住关于Haskell中括号和函数调用的规则:没有任何规则,因为括号中 与 有关函数调用!
Haskell中函数调用的基本语法是只写彼此相邻的术语:function argument
正在调用function
,并将其传递给argument
。在类C语法中,您将其写为function(argument)
。您的C示例f(comma, separated, args)
将在Haskell中以f comma separated args
编写。
Haskell仅在高中数学中使用括号时使用括号:对子表达式进行分组,以便获得不同的调用结构。例如,在数学中,1 + 2 * 3
会在2和3上调用*
,并在1上调用+
并调用*
调用的结果。 (1 + 2) * 3
更改分组,以便在1和2上调用+
,并且*
调用该结果和3.同样有效的Haskell(和C),具有相同的含义,但是像这样分组的括号对于使用普通函数而不是中缀运算符的表达式组也很有用。例如,f comma separated args
在f
,comma
和separated
参数上调用args
,而f comma (separated args)
则表示调用separated
它args
,并致电f
将comma
传递给separated
,并将调用结果传递给((((f) comma) separated) args)
。
不需要f comma separated args
;事实上,当您使用否括号时,您会看到该语言识别if ([string1 isEqualToString:string2]) {
NSLog(@"it is equal");
的方式。它将每个子表达式包装在显式括号中,因此没有歧义来向您显示默认值,而不是说您实际上需要所有这些括号。
答案 1 :(得分:1)
如果您习惯使用c风格的函数调用语法,那么对于c风格的函数,例如
// defining the function
int plus(int a, int b)
{
return a + b;
}
// elsewhere, calling the function
plus(a, b); // brackets surrounding only the arguments, comma separated
然后等效的Haskell代码将是
-- defining the function
plus :: Int -> Int -> Int
plus a b = a + b
-- elsewhere, calling the function:
(plus a b) -- brackets surrounding the function and the arguments, no commas
要使用问题中的示例,
f(comma, separated, args);
这相当于
(f comma separated args)
但是,除非有时将函数调用嵌入另一个表达式中,否则这些括号是不必要的。 在haskell中,这也等同于
((((f) comma) separated) args)
但是这些额外的括号也不是必需的,它们只是突出了Haskell处理函数应用程序的方式(其中每个函数技术上只接受一个参数);所以最后一种情况类似于以下c函数调用:
f(comma)(separated)(args);