我知道这听起来像是一个愚蠢的问题,但它是:Haskell 中有内置的阶乘吗?
谷歌给了我关于 Haskell 的教程,解释了我如何自己实现它,我在 Hoogle 上找不到任何东西。我不想每次需要时都重写它。
我可以product [1..n]
用作替代品,但是否有真正的Int -> Int
阶乘内置函数?
尽管它通常用于示例,但阶乘函数在实践中并不是很有用。这些数字增长得非常快,大多数包含阶乘函数的问题都可以(并且应该)以更有效的方式计算。
一个简单的例子是计算二项式系数。虽然可以将它们定义为
choose n k = factorial n `div` (factorial k * factorial (n-k))
不使用阶乘会更有效:
choose n 0 = 1
choose 0 k = 0
choose n k = choose (n-1) (k-1) * n `div` k
所以,不,它不包含在标准前奏中。斐波那契数列、阿克曼函数或许多其他函数,虽然理论上很有趣,但在实践中使用得不够普遍,无法在标准库中占有一席之地。
话虽如此, Hackage 上有许多数学库可用。
我在 Hackage 中知道的阶乘的最佳实现是Math.Combinatorics.Exact.Factorial.factorial
在exact-combinatorics
包中。它使用比 . 渐近更快的算法product [1..n]
。
不,但你可以很容易地写一个。如果您担心每次需要时都必须重写该函数,您总是可以将其编写为模块或库的一部分(取决于您想采用多远,以及您拥有多少其他类似的功能)。这样您只需要编写一次,并且可以在需要时快速将其拉入任何其他项目。
试试哈优!搜索(hackage顶部的链接);例如,它想出了这个
fac = product . flip take [1..]
您拥有product
标准前奏中的功能。结合范围,您可以轻松获得阶乘函数。
factorial n = product [n, n-1 .. 1]
nCr n r = n' `div` r'
where
-- unroll just what you need and nothing more
n' = product [n, n-1 .. n-r+1]
r' = factorial r
fact n = if n == 0 then 1 else n * fact(n-1)
fact n = foldl(*) 1 [1..n]
fact n = product [1..n]
你可以选择
如果您正在寻找 lambda 表达式,那么您始终可以使用经典的fix (\f x -> if x == 0 then 1 else x * (f (x - 1)))
.