将 defrecord 传递给函数 clojure

Passing defrecord into function clojure

我目前正在使用 Clojure 开发路线规划机器人。机器人接收一个包含一组停靠点的包裹,然后将该机器人传递到计算最短路线的函数中。

(defn journey [start end]
  (alg/pprint-path (alg/shortest-path all-edges {:start-node start, :end-node end, :cost-attr :weight})))


(defn fullpath [& stops]
  (doall (map (fn [a b] (journey a b)) stops (rest stops) )))

以上两个函数计算出停靠点之间的最短路线并打印出来。

;;passed into robot
(defrecord Parcel [start
                   end
                   home])

;;passed into robotroute to plan journey of robot
(defrecord Robot [stops]) 

;;computes the path
(defn robotroute [robot]
  (def stops (:stops robot))
  (fullpath stops))


(def task1parcel (Parcel. :main-office :r131 :main-office))
(def task1robot (Robot. task1parcel))
(def task1 (robotroute task1robot))

(task1)

以上是我创建机器人和包裹的代码。 Robotroute 是我将机器人传递到其中的功能,旨在去除停靠点并使用完整路径规划路线。

可以定义所有函数等。但是,当尝试 运行 任务 1 时,出现以下错误。

ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn  funcprog2.core/eval13519 (form-init1291893531842170235.clj:1)

任何人都可以协助修复此错误吗?

我还想要一个机器人来容纳多个包裹,这样它就可以连续运送多个包裹,最好的推进计划是什么?

(defn fullpath [& stops] (doall (map (fn [a b] (journey a b)) stops (rest stops) )))

function fullpath return 一个 lazyseq 。 (task1) 将再次评估此 lazeseq 也许您可以通过将 "task1" 放入 repl.

来获得结果

例如 (def list '(1 2 3)) 列表等于 '(1 2 3). (list) 最终会得到 "ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn"

还有一点就是试试

(defn robotroute [robot]
         (let [stops (:stops robot)] (fullpath stops)))

在 clojure 中,一个建议是:在定义函数时使用 let 而不是 def 来绑定变量,因为 def 意味着全局

  1. (def stops inside roboroute - 不应该是 let 吗?
  2. (robotroute task1robot) returns 任何 fullpath returns,这是 (doall (map ... - 它是一个序列 - 而序列不是 callable/not 函数(如错误所示)。因此像 (task1) 这样调用它失败了。