Следующий пример в clojure
вызывает нулевой и двоичный регистры +
различными способами:
(println 101 (+)) ; fine
(println 102 (+ (+) 4)) ; fine
(println 103 (reduce + (+) (range 4))) ; fine
(println 104 (reduce + (range 4))) ; fine
Я попытался заменить +
на mean-reducer
, как описано в thisсообщение в блоге (предупреждение: нет https) .
Я изменил функцию mean-reducer
, чтобы явно показывать ее элемент идентификации {:sum 0 :count 0}
при вызове без аргументов.
Это прекрасно работает дляпростые случаи приводят к (reduce mean-reducer (range 4))
, но падают для самого (reduce mean-reducer (range 4))
.
(defn mean-reducer
([] {:sum 0 :count 0})
([memo x]
{
:sum (+ x (memo :sum))
:count (inc (memo :count))
}))
(println 201 (mean-reducer)) ; fine
(println 202 (mean-reducer (mean-reducer) 4)) ; fine
(println 203 (reduce mean-reducer (mean-reducer) (range 4))) ; fine
;; (println 204 (reduce mean-reducer (range 4))) ; bad
запускается и выдает это с последней прокомментированной строкой.
% clojure mean_reducer.clj
201 {:sum 0, :count 0}
202 {:sum 4, :count 1}
203 {:sum 6, :count 4}
Сообщение об ошибке и трассировка стека, связанная с неудачным вызовом (reduce mean-reducer (range 4))
, выглядит следующим образом:
(~/clojure/mean_reducer.clj:12:62).
at clojure.lang.Compiler.load(Compiler.java:7647)
at clojure.lang.Compiler.loadFile(Compiler.java:7573)
at clojure.main$load_script.invokeStatic(main.clj:452)
at clojure.main$script_opt.invokeStatic(main.clj:512)
at clojure.main$script_opt.invoke(main.clj:507)
at clojure.main$main.invokeStatic(main.clj:598)
at clojure.main$main.doInvoke(main.clj:561)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:37)
Caused by: java.lang.ClassCastException: class java.lang.Long cannot be cast to class clojure.lang.IFn (java.lang.Long is in module java.base of loader 'bootstrap'; clojure.lang.IFn is in unnamed module of loader 'app')
at user$mean_reducer.invokeStatic(mean_reducer.clj:5)
at user$mean_reducer.invoke(mean_reducer.clj:1)
at clojure.lang.LongRange.reduce(LongRange.java:222)
at clojure.core$reduce.invokeStatic(core.clj:6823)
at clojure.core$reduce.invoke(core.clj:6810)
at user$eval143.invokeStatic(mean_reducer.clj:13)
at user$eval143.invoke(mean_reducer.clj:13)
at clojure.lang.Compiler.eval(Compiler.java:7176)
at clojure.lang.Compiler.load(Compiler.java:7635)
... 9 more
I думаю это означает, что каким-то образом линии пересекаются иэлемент (range 4)
привязан к memo
, но я не уверен, почему это произойдет, если случай с явным начальным элементом будет успешным.