我目前正在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)
有人可以协助修复此错误吗?
同样向前发展我希望机器人能够容纳多个包裹,这样它可以连续多次交付,最好的计划是什么呢?
答案 0 :(得分:1)
(defn fullpath [& stops]
(doall (map (fn [a b] (journey a b)) stops (rest stops) )))
函数fullpath返回一个lazyseq。 (task1)将再次评估这个lazeseq也许你可以通过放置" task1"来获得你的结果。在repl。
例如(def list '(1 2 3))
列表等于'(1 2 3). (list)
将最终得到" ClassCastException clojure.lang.PersistentList无法强制转换为clojure.lang.IFn"
另一点是尝试
(defn robotroute [robot]
(let [stops (:stops robot)] (fullpath stops)))
在clojure中有一个建议是:在定义函数时使用let而不是def来绑定变量,因为def意味着全局
答案 1 :(得分:1)
(def stops
- 不应该是let
吗?(robotroute task1robot)
返回fullpath
返回的任何内容,即(doall (map ...
- 它是一个序列 - 并且序列不可调用/不是函数(如错误所示)。因此,像(task1)
那样调用它会失败。