9

我正在编写一个自定义转换器作为练习,但我惊讶地发现它的 0-arity init 函数没有被调用。

为什么?

它与我使用的聚合函数有关吗?如果是,哪些会调用 init 函数,为什么其他人不会?

(defn inc-xf [xf]
  "inc-xf should be equivalent to (map inc)"
  (fn
    ;; init
    ([]
     (println "init") ;; <- this is not called (???)
     (xf))

    ;; step
    ([result input]
     (println "step" result input)
     (xf result (inc input)))

    ;; completion
    ([result]
     (println "completion" result)
     (xf result))))

(transduce inc-xf
           +
           100
           [5 5 5])
4

1 回答 1

6

如果您查看实现,transduce您可以看到会发生什么。

(defn transduce
  ;; To get the init value, (f) is used instead of ((xform f))
  ([xform f coll] (transduce xform f (f) coll))
  ([xform f init coll]
   ,,,))

然而,为什么更难回答。

实现零元的转换器是转换器要求的一部分,但它从未实际用于 clojure.core 中的任何转换上下文中。在邮件列表上,有一篇帖子与您提出了相同的问题,并提出了一个transduce实际使用 init arity 的实现方案。然而, jira 票被拒绝了,解释如下:

Rich 让我拒绝票,因为 xform 的 init arity 不应该参与减少函数的积累。- 亚历克斯·米勒

那么,如果转换器没有在任何地方使用,为什么它是合约的 init arity 部分?¯\_(ツ)_/¯

于 2018-02-18T18:09:09.093 回答