【发布时间】:2016-08-25 01:36:22
【问题描述】:
我怎样才能使用类似于recurnot at tail 位置的东西?
看看我的代码:
(defn -main [& args]
(println "Hi! Type a file name...")
(defn readFile[])
(let [fileName(read-line)]
(let [rdr (reader fileName)]
(if-not (.exists rdr)
((println "Sorry, this file doesn't exists. Type a valid file name...")
(recur)))
(defn list '())
(doseq [line (line-seq rdr)]
(if-not (= "" line)
(concat list '(line)))
(list))))
(defn fileLinesList (readFile))
...
...)
我知道我不能在这里使用recur...但我也不知道如何在 clojure 中使用它。
我是 Clojure 的新手,我来自 OOP 上下文。所以……
有没有办法在这种情况下使用递归? 有什么替代方案?
【问题讨论】:
-
您的目标是编写一个从文件中读取文本行的函数还是现有函数对您来说足够好?
-
虽然你没有这样写,但你的函数逻辑似乎是'如果 然后 否则 ',在这种情况下函数是尾递归的。所以我建议像这样重写它。
-
还有其他一些 Piotrek 没有提到的错误,但他的代码避免了这些错误。只是为了让您朝着正确的方向开始:(1)在 Clojure 中,没有一个日常常用函数实际上会修改一条数据,正如您的行
(concat list '(line))应该做的那样,因为它在doseq内.concat不能修改list;相反,它返回一条新数据,即其参数的串联。 -
(2)
'(line)将返回一个包含单个元素的列表,即符号line,但您想要的是该符号的内容。line应该没有括号或引号。 -
(3) 最后一行中的
(list)看起来返回的是在没有参数的情况下调用函数list的结果,返回的是空列表。当有一个不带引号的列表时,它的第一个参数通常被视为一个函数的名称,该函数将与列表的其他元素作为其参数进行评估(特殊情况除外,如引用列表时)。但是,在这种情况下,您已经重新定义了list,因此它不再引用函数。所以(list)会产生错误,而不是执行list通常命名的函数。
标签: recursion clojure functional-programming lisp tail-recursion