Has*_*921 1 haskell lambda-calculus
fac n = if n < 2 then 1 else n * fac (n-1)
main = do
putStrLn "Enter a number: "
number <- getLine
print $ number >>= fac
Run Code Online (Sandbox Code Playgroud)
我不知道如何在没有if语句的情况下编写递归因子函数.我们的教授说有关lambda演算的事情.
模式匹配和防护是两种特别简单的方法.防御本质上是if-then-else的另一种语法; 它们看起来像这样:
fac n | n < 2 = 1
| otherwise = n * fac (n-1)
Run Code Online (Sandbox Code Playgroud)
与if-then-else不同,它们干净地支持多种条件; 例如,人们也可以写
fac n | n < 0 = error "nah"
| n == 0 = 1
| n == 1 = 1
| n > 1 = n * fac (n-1)
Run Code Online (Sandbox Code Playgroud)
在if-then-else形式下看起来不那么美观.
通过模式匹配,通常可以编写多个定义方程:
fac 0 = 1
fac 1 = 1
fac n = n * fac (n-1)
Run Code Online (Sandbox Code Playgroud)
特别是对于数字,这也基本上是一个if-then-else; 但是对于编译器集成较少的数据类型,通常无法使用if-then-else进行模拟,并且通常会导致非常自然的代码.
另一个非常好的方法是将递归推送到现有的Prelude函数中; 在实践中你可以发现越多的迭代模式,你可以通过不重复实现相同的循环来避免更多的错误.对于这个,您可以使用product和特殊的枚举语法:
fac n = product [1..n]
Run Code Online (Sandbox Code Playgroud)
更先进(也更糟糕)的技术是定义一种新的数字; 例如,教堂数字允许数字的生产者驱动递归,而消费者(这里fac)只提供基本情况.在这种风格中,您可能会看到如下内容:
fac n = fst (n (1,1) (\(prod, sum) -> (prod*sum, sum+1)))
Run Code Online (Sandbox Code Playgroud)
(但注意哦,这需要一种非常特殊的号码-肯定的类型fac是不是可以接受的函数的一个Int或Integer!)这笑话是采取在其逻辑和结论令人震惊哈斯克尔程序员的演变.