我正在阅读Haskell的书,并且正在学习第8章。在进行练习时,我注意到一些我不理解的东西。

为什么这会导致堆栈溢出

mc x | x>100 = x-10
     | otherwise = mc $ mc x+11

但这不是

mc x | x>100 = x-10
     | otherwise = mc $ mc (x+11)

我认为这与第一个示例中未对x + 11进行评估有关,但并非总是像这样评估表达式

例如

Prelude> id 43+94
137

#1楼 票数:6 已采纳

第一个表达

mc $ mc x+11

被解释为

mc ((mc x) + 11)

因为函数应用程序优先于运算符。

第二种表达

mc $ mc (x+11)

被解释为:

mc (mc (x+11))

实际上,第一个确实不会得到评估,因为如果您这样写:

mc x | x > 100 = x-10
     | otherwise = mc ((mc x) + 11)

然后您根据mc x定义mc x 除非不对该表达式中的mc x求值,否则您将在计算mc x时调用mc x ,因此它将继续进行调用。

#2楼 票数:4

这完全是关于运算符优先级的。 特别是,功能应用程序优先于所有运算符。 所以这:

mc x+11

实际上被解析为

(mc x)+11

而您尝试“以视觉方式”通过间隔或缺少间隔来指示所需的分组这一事实没有任何区别。 当然,这就是为什么第二个版本效果更好的原因,因为您明确指出了想要的分组。

当然,意想不到的解释意味着,对于x <= 100 ,为了评估mc x ,编译器必须首先评估mc x ,依此类推。 因此,最终的堆栈溢出。

  ask by jamesfake namesmith translate from so

未解决问题?本站智能推荐:

2回复

递归函数haskell上的堆栈溢出

这是Haskell中幂函数的一种实现。 但是我有堆栈溢出错误。 不知道如何解决
3回复

Haskell堆栈溢出

我正在编写一种遗传算法来生成字符串“ helloworld”。 但是当n为10,000或更大时,evolve函数会产生堆栈溢出。 species pool = 8 ,由8个基因组成的库将复制到8个组中。 每组发生突变,并选择每组的最适体进行进一步进化(返回8个基因)。 的GitHub
4回复

是什么导致haskell中的“错误C堆栈溢出”通常

Hugs Haskell实现中“错误C堆栈溢出”的常见原因是什么?
1回复

Haskell递归堆栈溢出

我对Haskell来说还很陌生,非常抱歉。 但是-如何摆脱无尽的递归而不会被溢出。 这是代码: 编辑 : 我相信代码是不言自明的,但是:如果x等于2,则除以2,否则3 * x +1。这是著名的Collat​​z问题的一部分。
4回复

Haskell,memoization,堆栈溢出

我正在研究Project Euler的问题14( http://projecteuler.net/problem=14 )。 我正在尝试使用memoization,以便将给定数字的序列长度保存为部分结果。 我正在使用Data.MemoCombinators。 下面的程序产生堆栈溢出。
1回复

unsafeRead导致堆栈溢出

这里有一些代码可以在ideone上进行边界检查。 它成功运行,没有越界错误。 在这个代码中,在第34行,我已经将readArray更改为unsafeRead ,它仍然编译,但崩溃时堆栈溢出。 这是一个GHC错误还是我做错了什么?
2回复

Haskell-递归堆栈溢出

我试图将所有n从1加到一个非常大的数字(现在是10 ** 9),但它会给出堆栈溢出。 另外我不认为在1处停止并且在不同行中执行总和n是最有效的方式,但下面的代码是我对Haskell的全部知识。 我真的不太了解函数式编程,我想尽可能多的解释。 (我也试过把$!strict放在最后一行,这在其
2回复

我的Haskell代码中的堆栈溢出

我想找到换币的所有组合。 1,2,5,10,20,50,100和200.(1分,2分..)如果硬币超过500(5欧元),它应该给-1.My代码与那些测试用例完美配合:numOfSplits 10 (11)numOfSplits 20(41)numOfSplits 100(4563)。 当我尝