0

我无法从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])
4

2 回答 2

2
  • 您的第一个示例出错了,因为recur它位于cons- 而不是尾部位置(错误 - 请参阅下面的编辑)。错误消息具有误导性。
  • 第二个出错了,因为您在每次迭代中都应用cycle了您的。funs

我不想回答你的问题,所以...

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

(osc v (cycle funs))

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


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

将其表单lazy-seq参数包装为无参数函数,在这种情况下向翻译器提供

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

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

于 2014-05-08T21:45:10.900 回答
2

第一次尝试不起作用,因为惰性序列宏会在需要时从零参数 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)))

您的第二次尝试由于重复调用循环而出现问题,因此 (first fns) 第二次不是 fn - 它是 seq.

于 2014-05-08T21:53:09.507 回答