【问题标题】:Oscilating function in ClojureClojure 中的振荡函数
【发布时间】:2014-05-08 19:47:06
【问题描述】:

我无法从4clojure 站点解决这个问题,而且这些错误没有多大帮助:

;;Write an oscillating iterate: a function that takes an initial value and a
;;variable number of functions. It should return a lazy sequence of the functions
;;applied to the value in order, restarting from the first function after it hits the end.

(fn osc [value & funs]
  (loop [value value
         funs (cycle funs)]
    (cons value (lazy-seq
                 (recur ((first funs) value) (drop 1 funs))))))

此版本的函数显示此错误:

java.lang.IllegalArgumentException: Mismatched argument count to recur,
expected: 0 args, got: 2, compiling:(NO_SOURCE_PATH:0)

为什么recur 期待0 参数,但是我尝试尝试了其他功能:

(fn osc [value & funs]
  (let [value value
         funs (cycle funs)]
    (cons value (lazy-seq
                 (osc ((first funs) value) (drop 1 funs))))))

但它会产生这样的结果:

java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

我能想到的唯一错误位置是在 lazy-seq 函数之后,它在语法上似乎没问题。

这两个函数在这个测试中都失败了

(= (take 3 (__ 3.14 int double)) [3.14 3 3.0])

【问题讨论】:

  • 第二个版本缺少一个正确的单词:apply。只要找到合适的地方放它...

标签: clojure lazy-sequences


【解决方案1】:

第一次尝试不起作用,因为 lazy-seq 宏会在需要时从零参数 fn 调用您给它的主体。因此,即使您的代码位于尾部位置,它也处于另一个函数的尾部位置。必须爱宏。我建议运行 (source lazy-seq) 来亲自了解它。

(defn osc-seq [val fns]
  (cons val (lazy-seq (osc-seq ((first fns) val) (rest fns)))))

(defn osc [val & fns]
  (osc-seq val (cycle fns)))

由于重复调用循环,您的第二次尝试出现问题,因此(第一次 fns)第二次不是 fn - 这是一个序列。

【讨论】:

    【解决方案2】:
    • 您的第一个示例出错了,因为 recurcons 内 - 不在尾部位置(错误 - 请参阅下面的编辑)。错误消息具有误导性。
    • 第二个出错了,因为您将cycle 应用于您的funs on 每次迭代。

    我不想为你回答这个问题,所以……

    考虑一下,如果你可以这样调用你的第二个函数:

    (osc v (cycle funs))
    

    ...您不会在其中调用cycle。因此,构造一个这样的函数,使其成为您的明显函数的本地函数,并适当地调用它。


    @pete23 是对的。在您的第一个示例中,lazy-seq,而不是cons,排在第一位,以破坏recur 的尾部位置。

    macro lazy-seq 将其 form 参数包装为无参数函数,在这种情况下,向翻译器显示

    (fn [] (recur ((first funs) value) (drop 1 funs)))
    

    ... 其中,正如错误消息所述,recur 在预期为 0 时提供 2 个参数。由于这愚弄了我,也可能愚弄了其他人,因此我将完整地保留编辑线索。

    【讨论】:

      猜你喜欢
      • 2017-12-23
      • 1970-01-01
      • 2019-02-18
      • 2015-11-30
      • 2015-08-26
      • 2018-08-09
      • 1970-01-01
      • 2018-12-22
      • 2017-04-29
      相关资源
      最近更新 更多