Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 当我在另一个函数的应用程序中应用一个参数为n-1(没有括号)的函数时,为什么会出现无限递归?_Haskell - Fatal编程技术网

Haskell 当我在另一个函数的应用程序中应用一个参数为n-1(没有括号)的函数时,为什么会出现无限递归?

Haskell 当我在另一个函数的应用程序中应用一个参数为n-1(没有括号)的函数时,为什么会出现无限递归?,haskell,Haskell,这里我可以将参数7-1传递给函数f,不带括号 Prelude> f = (+1) Prelude> f 7-1 7 1. 为什么以下是一个无限递归 Prelude> addRec :: (Eq a, Num a) => a -> a; addRec 0 = 0; addRec n = n + addRec n-1; Prelude> addRec 5 2. 我可以通过在n-1 Prelude> addRec :: (Eq a, Num a) =>

这里我可以将参数
7-1
传递给函数
f
,不带括号

Prelude> f = (+1)
Prelude> f 7-1
7
1. 为什么以下是一个无限递归

Prelude> addRec :: (Eq a, Num a) => a -> a; addRec 0 = 0; addRec n = n + addRec n-1;
Prelude> addRec 5
2. 我可以通过在
n-1

Prelude> addRec :: (Eq a, Num a) => a -> a; addRec 0 = 0; addRec n = n + addRec (n-1);
3. 或者在整个
addRec
递归项上使用带括号的
$
运算符:

Prelude> addRec :: (Eq a, Num a) => a -> a; addRec 0 = 0; addRec n = n + (addRec $ n-1)
我想确切地了解每个表达式是如何工作的或不工作的

以下是我的推理:

addrecn=n(…)
中,我们有效地组合了两个函数(不使用
组合运算符)。我们正在编写
(+)
addRec
。本例中的Haskell是否理解我们有第三个函数
(-)

我们使用函数应用程序(据我所知,它是由函数后面的空格表示的运算符)来实现这种组合


函数应用程序是左关联的,所以我的第一个问题是:当我们添加与默认左关联性对应的括号时,
addRec n=n+addRec n-1
是什么样子

f7-1
并不是你认为它的意思

在Haskell中,函数应用程序具有最高优先级。这意味着
f7-1
始终被解释为
(f7)-1
。减号周围没有空格是不相关的,只是碰巧你得到了正确的答案:
f7=(+1)7=8
,然后
8-1=7
。如果将函数定义为
f=(*2)
,则不会发生这种情况

类似地,
addRec n-1
被解释为
(addRec n)-1
,因此每次都使用相同的参数
n
调用
addRec
,从而产生无限递归


修复它的两种方法,您已经知道:parens或operator
$

函数应用程序优先于所有其他运算符
addRec n-1
被解析为
(addRec n)-1
。你只能用显式括号或
$
操作符来解决这个问题。我不同意投票结果。这不是一个印刷错误,而是(非常常见的)对Haskell运算符优先规则的误解。这可能不是一个印刷错误,但我认为它不需要另一个解释基本优先规则的答案。我认为meta中有一个讨论指出,可以通过简单评论解决的琐碎问题可以包含在“不再复制”下。@chepner我不同意这是一个“琐碎”问题,因为如果是这样,可能会有重复的问题。此外,对一个人来说微不足道的事情对另一个人来说未必微不足道。我也不同意基于一些关于元的讨论,用错误的理由来结束一个问题。如果你想正式提出一个理由来结束一个问题,因为它是琐碎的,那没关系,但在那之前,对一个问题投否决票(因为“没有用”)比因为一个虚假的理由投票结束更合适。我认为这是如此基本,以至于没有一个重复,但有许多问题归结为同一个基本问题:不理解优先权。也许应该有一个单一的、规范的问题来处理这个问题,但我不确定如何最好地构建它。