单链表(插入[list elt])函数

时间:2014-10-10 05:32:25

标签: clojure insert singly-linked-list

如果我没有发现这个错误,我将会失去理智。我实现了一个单链表的版本:

(ns clojure_fun.core)
(defprotocol MConsP
  (elt [this] "returns elt")
  (cdr [this] "returns cdr")
  (set-elt! [this val] "set elt")
  (set-cdr! [this val] "set cdr")
  )

(deftype MCons [^{:unsynchronized-mutable true} elt
                ^{:unsynchronized-mutable true} cdr]
  MConsP
  (elt [this] elt)
  (cdr [this] cdr)
  (set-elt! [this val] (set! elt val))
  (set-cdr! [this val] (set! cdr val))
  )

(defn mcons [a b] (MCons. a b))
(defn mlist [& xx]
  (if (empty? xx) nil
      (mcons (first xx) (apply mlist (rest xx))))
  )

(defn insert [xx elt]
  (cond (nil? xx) (mcons elt nil)
        (< elt (-> xx cdr elt))
              (set-cdr! xx (mcons elt (cdr xx)))
        :else (insert (cdr xx) elt))
  )

(def x (mlist 1 3 4 5 6))
(insert x 2)

当我尝试评估最后一行(insert x 2)时,我收到以下错误:

CompilerException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn, compiling:(clojure_fun/core.clj:1:26)

很长一段时间我都没那么难过。可能是因为我只是在学习Clojure。

提前致谢。

1 个答案:

答案 0 :(得分:2)

问题在于:

(< elt (-> xx cdr elt))

在您的本地范围内,elt很长,您尝试将elt函数(现在由本地隐藏)应用于(cdr xx)。只需将elt参数重命名为其他内容。