0

SRFI 42の熱心な内包表記には、いくつかの条件が成立している間、ジェネレーターを実行する句を含めることができます:while。たとえば、次のようになります:リストを(list-ec (:while (:range i 10) (< (* i i) 50)) i)返します(0 1 2 3 4 5 6 7)(そして7 で反復を停止ifします。 in のように(list-ec (:range i 10) (if (< (* i i) 50)) i)続行するが、それ以上の値を生成しません)。

Racket では、一般的にネイティブのforandを使用することを好みますfor/listが、この組み込みのようなものはないようです。:whileラケットでシミュレートする最良の方法は何forですか?

4

2 に答える 2

7

#:breakこの句をforループで使用して、同様のことを行うことができます。たとえば、これは私があなたの例と同等だと思うものです:

(for/list ([i (in-range 0 10)]
           #:break (> (* i i) 50))
     i)

#:breakこれにより、条件が成立したときに反復が停止します。#:when停止する代わりに反復をフィルタリングするために使用することもできます。その他のオプションについてはドキュメントの を参照してください。

于 2013-05-15T21:45:37.753 に答える
3

どういうわけかドキュメントでそれを見逃しました: 答えはstop-beforefunctionを使用することです。次のように翻訳できます。

(list-ec (:while (:integers i) (< (* i i) 10))
         (:while (:integers j) (< (* (+ i 1) j) 10))
       (list i j))

(for*/list
     ([i (stop-before (in-naturals 0) (λ (i) (>= (* i i) 10)))]
      [j (stop-before (in-naturals 0) (λ (j) (>= (* (+ i 1) j) 10)))])
  (list i j))

デフォルトでネストされたループを生成するfor*/listため、スター付きバージョンが必要であることに注意してください。list-ecまた、#:breakAsumu Takikawa が指摘したように、Racket の理解には節がありますが、それは別の方法で機能します。単一のジェネレーターを制限するのではなく、ループ全体を終了します。

于 2013-05-16T04:01:21.193 に答える