Search 在clojure中,如何使搜索过程在找到答案后立即返回

Search 在clojure中,如何使搜索过程在找到答案后立即返回,search,clojure,functional-programming,Search,Clojure,Functional Programming,这里是Clojure新手 我在Clojure解决一个搜索问题。 在搜索问题中,一找到答案就提前返回是很常见的。 例如,在Java中 boolean search(State x) { if (finishState(x)) return true; for (State y: expand(x)) { if (search(y)) return true; // Return early } } 我被困在如何在Clojure中实现这一点上,因为Clojure没有return

这里是Clojure新手

我在Clojure解决一个搜索问题。 在搜索问题中,一找到答案就提前返回是很常见的。 例如,在Java中

boolean search(State x) {
  if (finishState(x)) return true;
  for (State y: expand(x)) {
    if (search(y)) return true; // Return early
  }
}
我被困在如何在Clojure中实现这一点上,因为Clojure没有return语句。 我必须绘制x的每个扩展状态的所有结果,看看其中是否有一个真值。但是,这种方法没有利用短路,而且性能很差,因为它遍历了所有的搜索树

(some true? (map search (expand x)))
在这里,
宏没有帮助,我知道存在
lazy seq
,但是
真的有必要吗?实现这一点的理想方法是什么?

map
返回一个惰性序列

当您使用
some true?
时,将以增量方式使用该惰性序列,在第一个元素上调用
search
,然后在第二个元素(如果需要)上调用,然后在第三个元素(如果需要)上调用。。。直到第一次
search
返回
true


因此它默认使用“短路”。

如果只需要找到一个元素,请将
reduce
reduced
一起使用

(reduce (fn [_ elem]
           (if (pred elem)
             (reduced elem))) 
        nil input)
pred
被假定为一个函数,当使用所需元素调用该函数时,该函数返回一个
非零值

请注意,reduce的lambda参数采用一个(在上面的示例中为未使用的,因此绑定为
\uu
)第一个累加器参数。它在每一步都会反弹到lambda上次返回的值,因此如果您没有找到所需的元素,可以使用lambda返回值跟踪下一步的值

请注意,
reduced
返回一个特殊值,该值允许
reduce
立即停止使用输入

据我所知,与惰性序列过滤和循环相比,这种策略通常能提供最好的性能