【发布时间】:2016-02-11 09:31:41
【问题描述】:
我正在使用函数iterate 创建一个惰性序列。该序列不断在每个项目上产生新值。然而,在某一时刻,产生的值“不再有意义”,因此它们毫无用处。这应该是惰性序列的结束。这是抽象形式的预期行为。
我的方法是让序列产生值。一旦检测到它们不再有用,序列只会发出 nil 值。然后,该序列将用一个 take-while 包装,使其成为有限的。
简化:
(take-while (comp not nil?)
(iterate #(let [v (myfunction1 %)]
(if (mypred? (myfunction2 v)) v nil)) start-value))
这可行,但这里出现了两个问题: 用 nil 作为“停止器”对有限惰性序列进行建模通常是一个好主意,还是有更好的方法?
第二个问题与我实现上述机制的方式有关,尤其是在迭代内部。 问题是:我需要一个函数来获取一个值,然后是一个谓词来测试它是否有效,如果是:in 需要传递第二个函数,否则:返回 nil。 我正在寻找一种不太重要的方式来实现这一点,更具体地省略 let 语句。而是这样的:
(defn pass-if-true [pred v f]
(when (pred? v) (f v)))
#(pass-if-true mypred? (myfunction1 %) myfunction2)
现在,我会这样做:
(comp #(when (mypred? %) (myfunction2 %)) myfunction1)
【问题讨论】:
-
顺便说一句:
(comp not nil?)不如(complement nil?)。(if (mypred? (myfunction2 v)) v nil)也可以替换为(when (mypred? (myfunction2 v)) v)
标签: clojure functional-programming clojurescript