1

是否可以使用 #, %1, %2 来编写以下代码?

(defn fib-step [[a b]]
  [b (+ a b)])

(defn fib-seq []
  (map first (iterate fib-step [0 1])))

user> (take 20 (fib-seq))
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)

简而言之,我想知道如何使用 # 和 % 语法糖编写向量 -> 向量函数。

谢谢

4

4 回答 4

3

您可以使用带有线程宏的#()阅读器表单轻松生成向量。->例如,以下两个函数是等价的:

(fn [a b] [b a])
#(-> [%2 %])

但是,如果您需要进行解构,就像您的情况一样,您最好只坚持使用fn具有显式参数列表的一种形式。你能得到的最好#()的东西是这样的:

#(-> [(% 1) (+ (% 0) (% 1))])

或者

#(-> [(% 1) (apply + %)])

使用高阶juxt函数是另一种创建向量的好方法,但不幸的是,在这种情况下,它也不会给你带来太多好处:

(def fib-step (juxt second #(apply + %)))

我认为在所有选项中, usingfn仍然是最合适的,因为它易于支持解构:

(fn [[a b]] [b (+ a b)])
于 2013-07-02T01:30:13.820 回答
0

我认为使用该vector功能比(-> [...])“技巧”更清楚:

#(vector (% 1) (apply + %))

尽管在这种情况下,通过解构,我只会使用命名函数或(fn [...] ...) 无论如何。

于 2013-07-02T06:28:55.357 回答
0

我建议fib-step使用 2 个参数而不是向量,因为这样可以更清楚地表明该函数需要两个值,而向量作为参数意味着它可以将任意数量的值作为参数(以向量的形式)。

(def fib-step #(-> [%2 (+ %1 %2)]))

(defn fib-seq []
  (map first (iterate (partial apply fib-step) [0 1])))
于 2013-07-02T04:32:27.147 回答
0

这是代码:

(def step #(-> [(% 1) (+ (% 0) (% 1))]))
(def fib #(map first (iterate step [0 1])))

(println 
 (take 20 (fib))
)

或者

(def step #(-> [(% 1) (+ (% 0) (% 1))]))
(def fib (->> [0 1]
              (iterate step)
              (map first)))

(println
  (->> fib 
       (take 20))
))
于 2013-07-02T02:50:26.880 回答