(ns src.helloworld)
(defn fibonacci[a b] (println a b (fibonacci (+ b 1) a + b)))
(fibonacci 0 1)
我是功能编程的新手,并决定开始学习Clojure,因为它与C#的非常不同。我想拓宽视野。
这是我得到的错误:
Clojure 1.2.0
java.lang.IllegalArgumentException:
Wrong number of args (4) passed to:
helloworld$fibonacci
(helloworld.clj:0) 1:1 user=>
#<Namespace src.helloworld> 1:2 src.helloworld=>
数学问题从来都不是我的强项,而且我从来没有做过任何操纵过这样的数字的事情,所以我希望你能提供任何指导。
请不要给我整个解决方案。
最好是我想要一些好的提示,也许是它应该是什么样子的骨架。
答案 0 :(得分:4)
(fibonacci (+ b 1) a + b)
在这里,您使用四个参数调用函数fibonacci
:(+ b 1)
的结果,变量a
的值,函数+
和值{变量b
。由于fibonacci
被定义为只接受两个参数,因此您会收到错误。
修复此问题后,您将收到堆栈溢出错误而不会看到任何输出。这是因为您将fibonacci
的递归调用作为println
的参数。因此它会在执行println
之前尝试执行递归调用。由于递归是无限的,因此对println
的调用永远不会发生。你应该做的是先打印数字,然后递归调用fibonacci
。
一旦你这样做,程序将打印很多数字,但堆栈最终仍会溢出。这是因为clojure不会优化尾调用,因此即使使用尾递归,无限递归也会导致堆栈溢出。为了防止这种情况,请使用recur
表单而不是正常的递归。
除了这些要点之外,当您错误地实施Fibonacci序列时,您的程序将打印错误的数字。
答案 1 :(得分:3)
这是一个关于你为什么会遇到错误的提示。您将以下四个参数传递给fibonacci
:
(+ b 1)
a
+
b
。那仍然不会给你一个工作函数,这里有一个暗示:什么会导致代码停止执行并向用户返回一个值?
答案 2 :(得分:1)
其他答案向您解释函数调用中的错误。修复之后你应该考虑使用loop / recur来进行尾调用优化,因此不会在每次递归调用时使用堆栈。如果没有给你完整的东西,那么很难给出一个例子: - /这是另一个线程,他们在clojure中使用递归计算一个阶乘:Factorial
答案 3 :(得分:1)
当我通过一些类似的代码katas学习时,我发现这个网站非常有用。 Coding Kata。它们具有作为黄带kata的纤维序列。他们还提供了多种语言的人们发布的解决方案(Clojure就是其中之一)。这样,您可以将您的答案与其他人进行比较,看看您是否能够获得任何提示或更好的做事方式。
答案 4 :(得分:0)
当你完成后,你可能希望在Stu Halloway的 Programming Clojure 中看一下Christophe Grand的Fibonacci解决方案。这是我见过的最优雅的解决方案。它是在第1版的第137页(因为我听说有第2版即将推出)。