0

我在 Clojure 中运行我的程序时遇到问题。我几周前才开始学习 Clojure。所以我不知道调试 Clojure 程序的快速简便的方法。我的 func2 引发异常(adj(a b))如下:

ClassCastException java.lang.Long 无法转换为 clojure.lang.IFn 用户/func2。

我不知道它有什么问题。有人可以指出我的编码问题吗?在func3中,我func2递归调用,但它抛出:

ArityException 传递给的 args (0) 数量错误:PersistentVector clojure.lan g.AFn.throwArity (AFn.java:437)

func3有什么问题?谢谢你。

(defn adj [value1 value2]
    (def result (+ (/ value1 2) (/ value2 2)))  
    (if (= (mod result 2) 1)
        (+ result 1)
        result
    )
)

(defn func2 [list]
    (let [[a b c d] list] 
        (inc d)
        ([(adj c a) (adj a b) (adj b c) d]))    
)

(defn func3 [list]
    (loop [v list r []]

    (if(= (v 0) (v 1) (v 2))
        (conj list r)               
        (func3(func2(list)))
    ))
)
4

2 回答 2

3

这些功能的预期结果是什么?我们可能需要查看一些示例输入和预期结果才能真正为您提供帮助。

这是我清理它们的尝试。我已经注意到我在评论中所做的更改。func3最严重的问题在于它是无限递归 - 没有结束条件。什么应该导致它停止工作并返回结果?

(defn adj [value1 value2]
   ;; don't use def within functions, use let
  (let [result (+ (/ value1 2) (/ value2 2))]
    (if (= (mod result 2) 1)
      (+ result 1)
      result)))

(defn func2 [list]
  (let [[a b c d] list]
    ;; The extra parens around this vector were causing it
    ;; to be called as a function, which I don't think is
    ;; what you intended:
    [(adj c a) (adj a b) (adj b c) d]))

;; This needs an end condition - it's an infinite recursion
(defn func3 [list]
  (loop [v list r []]
    (if (= (v 0) (v 1) (v 2))
      (conj list r)
      ;; Removed extra parens around list
      (func3 (func2 list)))))

我说不要def在函数内使用的原因是它总是创建一个全局函数。对于您想要的本地绑定let

[1 2 3]关于额外的括号,和之间的区别在于([1 2 3])前者返回一个包含数字 1、2 和 3 的向量,而后者试图将该向量作为函数调用。func2您在 in和listin周围的文字向量周围有多余的括号func3,这导致了异常。

作为风格说明,名称list不是一个好的选择。一方面,它是 shadowing clojure.core/list,另一方面,您可能正在使用向量而不是列表。coll使用(for collection) 或s(for sequence) 作为名称会更惯用。

这将表明至少有另一个变化。在func3您使用仅矢量功能(使用矢量作为函数以按索引执行查找)时,因此更通用(接受其他数据结构)您可以转换为带有以下内容的矢量vec

(defn func3 [coll]
  (loop [v (vec coll) r []]
    (if (= (v 0) (v 1) (v 2))
      (conj v r)
      (func3 (func2 v)))))
于 2013-11-05T03:55:14.350 回答
0

哦,没有必要调试它。我建议你看看 LightTable。

前两个功能很容易修复:

(defn adj [value1 value2]
  ;(def result (+ (/ value1 2) (/ value2 2))) def creates a global binding in current namespace !!!  
  (let [result (+ (/ value1 2) (/ value2 2))]  
  (if 
    (= (mod result 2) 1)
    (inc result)
    result)))

(defn func2 [xx]
  (let [[a b c d] xx] 
    [ (adj c a) (adj a b) (adj b c) (inc d)]
    ))

第三个功能我不清楚。我没有读懂你的意图。我的理解是:“继续将 func2 应用于自身,直到其结果的前三个元素相等。” 但是我担心这个条件永远不会满足,所以我用一个 true 替换它,以便只看到一个结果而不破坏堆栈。

(defn func3 [xx]
  (loop [ v (func2 xx) ]
    (if
      ;(= (v 0) (v 1) (v 2))
      true
      v               
      (recur (func2 v))
    )))

有用的链接:http ://clojure.org/cheatsheet

干杯 -

于 2013-11-06T03:09:18.837 回答