困惑:Clojure for loop with:while->;意外行为?

困惑:Clojure for loop with:while->;意外行为?,clojure,Clojure,我一直在学习Clojure,并对以下内容感到困惑: user=> (for [a (range 1 4) b (range 1 4)] [a b]) ([1 1] [1 2] [1 3] [2 1] [2 2] [2 3] [3 1] [3 2] [3 3]); _no surprise here_ 让我们添加:虽然(not=ab),但我希望看到一个空列表,因为如果条件为false,循环应该停止。在本例中,它是a=b=1的第一项。让我们看看: user=> (for [a (ran

我一直在学习Clojure,并对以下内容感到困惑:

user=> (for [a (range 1 4) b (range 1 4)] [a b])
([1 1] [1 2] [1 3] [2 1] [2 2] [2 3] [3 1] [3 2] [3 3]); _no surprise here_
让我们添加
:虽然(not=ab)
,但我希望看到一个空列表,因为如果条件为false,循环应该停止。在本例中,它是
a
=
b
=1的第一项。让我们看看:

user=> (for [a (range 1 4) b (range 1 4) :while (not= a b) ] [a b])

([2 1] [3 1] [3 2]) ; _surprise!_
:while
更改为
:when
以筛选出
(=ab)

user=> (for [a (range 1 4) b (range 1 4) :when (not= a b) ] [a b])
([1 2] [1 3] [2 1] [2 3] [3 1] [3 2]); _expected_
有人能解释一下为什么
(对于[…:while…]…)
的行为是这样的吗

我在OSX上使用Clojure1.3


感谢您,并为缺少格式表示歉意。这是我关于StackOverflow的处女帖子。

让我们看看每个迭代

a = 1
  b = 1 -> a == b, break because of while

a = 2
  b = 1 -> a != b, print [2 1]
  b = 2 -> a == b, break because of while

a = 3
  b = 1 -> a != b, print [3 1]
  b = 2 -> a != b, print [3 2]
  b = 3 -> a == b, break because of while

:而
for
中的
条件仅终止最内部的循环。我一直用
来表示
,但是
:虽然
很少,我从未意识到这一点;谢谢你的提问

遗憾的是,我认为最好的办法是在
for
周围包装一个
take while
,因为您希望在输出序列上有一个“全局”停止计数器,而不是在迭代的输入序列上有一个停止计数器。例如:

(->> (for [a (range 1 4)
           b (range 1 4)]
       [a b])
     (take-while (fn [[a b]] (not= a b))))

()

谢谢你,尼基塔。如果:虽然只适用于内部循环,但如何使其也适用于外部循环?我的问题是:(for[from[:a:b:c:d:e:f]到[:a:b:c:d:e:f]:let[path(find path a b)]:while path)path);当path为零时循环应该停止。对不起,我的意思是(for[from[:a:b:c:d:e:f]到[:a:b:c:d:e:f]:let[path(find path from to)]:while path]path@jbear,我不知道:(可能你最好创建路径的惰性序列,并在它们不为空时执行。我不确定
for
是否是惰性的。
:虽然
测试适用于它前面的序列,但不一定是最内部的循环。感谢你的澄清,Alex。鉴于语言的突出性,我无法帮助eeling有点失望的是,列表理解这一基本构建块应该是相当有限的。希望随着我的学习进展,在大家的大力帮助下,我会发现更多/更好的方法来完成它。@jbear实际上,这种方法比另一种方法限制更小。这样,你可以轻松地包装它如果您想要“全局”行为,请在
take while中使用
for
表达式。但是如果“全局”行为是
for/:while
所做的,您将如何取回当前的“intermediate”行为?你必须完全放弃
,而建立一个由map、mapcat、filter和take-while组成的老鼠窝。谢谢你的有见地的评论。我没有考虑过其他行为。现在一切都有了完美的意义:我对
的设计缺乏理解,而不是疏忽。