我想將Java Apache Maths 3封裝到Clojure中,但是我遇到了一個我不明白的問題。Clojure和Java interop:返回void的函數
這裏是的Javadoc:
http://commons.apache.org/proper/commons-math/javadocs/api-3.3/index.html
addValue
增加了一個值的對象,但返回void的方法。我想象這個對象內有一些內部數據。
在Java中,我會做:
regression.addValue(1,2);
我Clojure中定義的函數把它包起來:
;;----------Simple regression object builder----------
(defn simple-regression []
(SimpleRegression.))
;;----------Add points----------
(defn add-point
([reg [x y]]
(.addData reg (double x) (double y)))
([reg x y]
(.addData reg (double x) (double y))))
(defn add-points
([data reg]
(let [x (data :x)
y (data :y)
d (zipmap x y)]
(map (fn [[k v]] (add-point reg k v)) d)))
([x y reg]
(let [d (zipmap x y)]
(map (fn [[k v]] (add-point reg k v)) d))))
的功能很好地工作,當我在一個REPL單獨使用它。
我再定義一個完整的包裝:
(defn lin-reg
([data & {:keys [type] :or {type "simple"}}]
(let [reg (simple-regression)]
(do (add-points data reg)
(cond (= type "simple")
[(.getSlope reg) (.getIntercept reg)]
(= type "extended")
{:params [(.getSlope reg) (.getIntercept reg)] :r (.getR reg) :r2 (.getRSquare reg) :significance (.getSignificance reg)}
(= type "full")
{:params [(.getSlope reg) (.getIntercept reg)] :r (.getR reg) :r2 (.getRSquare reg) :significance (.getSignificance reg)
:conf-intervals [(.getSlopeConfidenceInterval reg) (.getInterceptConfidenceInterval reg)] :params-sse [(.getSlopeStdErr reg) (.getInterceptStdErr reg)]
:sse (.getSumSquaredErrors reg) :ssto (.getTotalSumSquares reg) :ssm (.getRegressionSumSquares reg) :cross-products-sum (.getSumOfCrossProducts reg)}
:else
(println "regression type can only be : simple, extended or full"))))))
代碼不起作用(回報[楠楠],這樣就意味着價值尚未添加),證實當我嘗試(.getN REG) = 0 如果我單獨試一下,我的意思是第一
(def reg (simple-regression))
(add-points {:x [1 2 3] :y [0.1 0.2 0.3]} reg)
[(.getSlope reg) (.getIntercept reg)]
沒有問題,所有的作品。
但是在函數裏面,沒有。我嘗試了很多版本,其中一個有一個
_ (add-points data reg)
我有一個印象,在函數內部,不會添加點。如果我複製粘貼do
也是一樣。
是否有更通用的Java機制我缺少像對象不能更改函數內?由於
非常感謝,看起來我錯過了很多關於Clojure的知識。我用doall解決了這個問題,因爲它不適合大量計算,但我會考慮在使用doseq之後! –
你被「懶蟲」咬了,它只會在你不看的時候咬人;-) –