Haskell 阶乘实现

问题描述

我实现了 factorial,如下所示。

factorial n = n * factorial(n-1)
factorial 0 = 1

不幸的是上面的代码抛出

C 堆栈溢出

然后我把代码改成这样:

factorial 0 = 1
factorial n = n * factorial(n-1)

终于成功了。
谁能告诉我第一个代码和第二个代码间的区别?

解决方法

您提供了两种情况:

factorial n = n * factorial (n - 1)
factorial 0 = 0

当您尝试 factorial 0 时,Haskell 将尝试将 0 与您的两个案例中的每一个匹配,从最上面的案例开始。由于大小写 n0 匹配(实际上与任何东西都匹配),因此您将始终使用最上面的一行,就像您只写过

factorial n = n * factorial (n - 1)

另一方面,如果您颠倒顺序,Haskell 将首先尝试将 00 匹配,从而触发 factorial 0 = 1 情况。

,

在第一个定义中使用 n 的模式匹配取代了第二个模式中的文字 0。 Haskell 将根据顺序进行匹配。由于 n 匹配任何数字(包括 0),因此您永远不会遇到 0 的基本情况。

第二个定义减轻了这个错误。