SICP,延续传球风格和Clojure的蹦床

问题描述:

我与SICP一起工作,运动2.29-b让我有机会在穿越手机和分支时获得延续传球风格。SICP,延续传球风格和Clojure的蹦床

为了简化故事,每个手机都有左右分支,它们由长度和数字权重或其他手机组成。这个问题要求找到手机的总重量。

第一相互递归解决方案之后,很简单,我尝试并成功实施了CPS'之一:

(defn total-weight-cps [mobile] 
    (letfn 
    [(branch-weight-cps 
     [branch kont] 
     (let [structure (branch-structure branch)] 
     (if (mobile? (branch-structure branch)) 
      (do (println "then " structure) (kont (traverse-mobile-cps structure identity))) 
      (do (println "else " structure) (kont structure))))) 

    (traverse-mobile-cps 
     [mobile kont] 
     (branch-weight-cps (left-branch mobile) 
         (fn [left-weight] 
          (branch-weight-cps (right-branch mobile) 
               (fn [right-weight] (kont (+ left-weight right-weight)))))))] 

    (traverse-mobile-cps mobile identity))) 

在这一点上,我曾尝试申请蹦床,以维护我的筹码。但有以下例外吹:

java.lang.ClassCastException: sicp_clojure.2_1_exercises_2_24_2_32$total_weight_STAR_$traverse_mobile_cps__6694$fn__6695$fn__6696$fn__6697 cannot be cast to java.lang.Number 
Numbers.java:126 clojure.lang.Numbers.add 
.../git/sicp-clojure/src/sicp_clojure/2_1_exercises_2_24_2_32.clj:185 sicp-clojure.2-1-exercises-2-24-2-32/total-weight*[fn] 
core.clj:5801 clojure.core/trampoline 
core.clj:5806 clojure.core/trampoline 
RestFn.java:439 clojure.lang.RestFn.invoke 
.../git/sicp-clojure/src/sicp_clojure/2_1_exercises_2_24_2_32.clj:186 sicp-clojure.2-1-exercises-2-24-2-32/total-weight* 

使用蹦床,以下的优秀link的代码是:

(defn total-weight* [mobile] 
    (letfn 
    [(branch-weight-cps 
     [branch kont] 
     (let [structure (branch-structure branch)] 
     (if (mobile? (branch-structure branch)) 
      (do (println "then " structure) (kont (traverse-mobile-cps structure identity))) 
      (do (println "else " structure) (kont structure))))) 

    (traverse-mobile-cps 
     [mobile kont] 
     (branch-weight-cps (left-branch mobile) 
         (fn [left-weight] 
          (branch-weight-cps (right-branch mobile) 
               (fn [right-weight] #(kont (+ left-weight right-weight)))))))] 
    (trampoline traverse-mobile-cps mobile identity))) 

最后一些样本数据:

(def branch11 (make-branch 1 1)) 
(def branch22 (make-branch 2 2)) 
(def branch36 (make-branch 3 6)) 
(def branch43 (make-branch 4 3)) 

(def mobile11-43 (make-mobile branch11 branch43)) 
(def mobile36-22 (make-mobile branch36 branch22)) 

(def branch5m1143 (make-branch 5 mobile11-43)) 
(def branch7m3622 (make-branch 7 mobile36-22)) 
(def mobile5m1143-7m3622 (make-mobile branch5m1143 branch7m3622)) 

(total-weight* mobile5m1143-7m3622) 

为什么它爆炸?

+1

你问为什么它炸毁?你从来没有真正保持你的问题。 – user100464 2014-10-19 18:55:14

+0

对不起,是的,编辑。 – 2014-10-20 11:18:06

继在我的岗位同样的链接,我已经解决了把我的执行情况:

(defn total-weight* [mobile] 
    (letfn 
    [(branch-weight-cps 
     [branch kont] 
     (let [structure (branch-structure branch)] 
     (if (mobile? (branch-structure branch)) 
      (fn [] (traverse-mobile-cps structure kont)) 
      (fn [] (kont structure))))) 

    (traverse-mobile-cps 
     [mobile kont] 
     (branch-weight-cps (left-branch mobile) 
         (fn [left-weight] 
          (branch-weight-cps (right-branch mobile) 
               (fn [right-weight] #(kont (+ left-weight right-weight)))))))] 
    (trampoline traverse-mobile-cps mobile identity)))