【问题标题】:Difference between iterate and repeatedly applying a function迭代和重复应用函数之间的区别
【发布时间】:2012-09-08 09:26:45
【问题描述】:

我正在研究 Clojure Koans:

https://github.com/functional-koans/clojure-koans/blob/master/src/koans/10_lazy_sequences.clj

我被这个卡住了:

"Iteration can be used for repetition"
  (= (repeat 100 :foo)
     (take 100 (iterate ___ :foo)))

我不知道填充 _ 空格的确切内置函数,所以我尝试自己编写。我把它写成一个单独的函数作为测试。

我希望这个是:如果 x 是一个序列,那么只需重复它的第一个元素。否则,将其设为 seq。

(def f (fn [x] (if (seq? x) (cons (first x) x) (cons x '()))))

当我显式运行它时,它看起来很好:

user=> (f :abc)
(:abc)
user=> (f (f :abc))
(:abc :abc)
user=> (f (f (f :abc)))
(:abc :abc :abc)

但是使用iterate会增加一个额外的括号:

user=> (take 1 (iterate f :abc))(:abc)
user=> (take 2 (iterate f :abc))
(:abc (:abc))
user=> (take 3 (iterate f :abc))
(:abc (:abc) (:abc :abc))

What causes this?

【问题讨论】:

  • 顺便说一句,确切的内置函数是 identity
  • 是的。不幸的是,我无法弄清楚公案并查看了其他人的解决方案。
  • koans 并不总是能很好地建立你的知识。我确切地知道我想要的功能,但是因为 Clojure 有很多内置概念,所以直到我来到这里才知道它被称为身份!
  • keyword 函数也恰好解决了这个特定情况。虽然这只是一个副作用,identity 是“正确”答案:-)

标签: clojure


【解决方案1】:
(fn [x] x)

解决这个特殊的公案

【讨论】:

    【解决方案2】:

    iterate重新阅读documentation

    返回 x、(f x)、(f (f x)) 等的惰性序列。

    如果您想要特定迭代的结果,请使用 nth 而不是 take

    用户=> (nth (迭代 f :abc) 0) :abc 用户=> (nth (迭代 f :abc) 1) (:abc) 用户=> (nth (迭代 f :abc) 2) (:abc:abc) 用户=> (nth (迭代 f :abc) 3) (:abc :abc :abc)

    【讨论】:

    • 谢谢。我在那里感到困惑。
    【解决方案3】:

    我已经用#(keyword %)解决了

    我已尝试使用#( %),但它不起作用。有谁知道为什么?

    【讨论】:

    • 我只用keyword 解决了这个问题。我也先尝试了#(%)。问题是匿名函数仍然将表单中的第一项视为函数,因此它最终将 :foo 视为没有参数的函数。这也适用于#(do %)
    • 我也可以使用#(-> %)
    • 我后来遇到了identity,它是 clojure.core 的一部分,并返回传递给它的任何内容。
    猜你喜欢
    • 1970-01-01
    • 2020-03-05
    • 2013-02-14
    • 2016-01-23
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2017-02-10
    相关资源
    最近更新 更多