3

私はコードを持っています

(define alternate
(letrec ([f (lambda (x) (cons x (lambda () (f (+ x 1)))))])
(lambda () (f 1))))

結果は1,2,3.です。1,2,1,2,1,2。を取るように変更するにはどうすればよいですか。

私はfの中で短所を試しましたが、うまくいきませんでした。何か案は?

4

3 に答える 3

1

これは、ストリームを使用して実装するのは簡単です。

(define (alternate)
  (stream-map (lambda (x)
                (if (even? x) 1 2))
              (in-naturals)))

ここでの秘訣は、stream-consを使用してストリームを構築することです。これは、基本的に手動で実装していることを実行します。つまり、必要な場合にのみ評価される要素が「promises」であるリストを作成します。

stream-consレイジーストリームを生成します。stream-firstはfirst-exprの評価を強制してストリームの最初の要素を生成し、stream-restはrest-exprの評価を強制して残りの返されるストリームのストリームを生成します。

これはalternate、フォームの要素の無限のストリームを返す方法を示しています1 2 1 2 1 2 ...

(define alt (alternate))

(stream-ref alt 0)
=> 1
(stream-ref alt 1)
=> 2
(stream-ref alt 2)
=> 1
(stream-ref alt 3)
=> 2

または、シーケンスのn個の要素のリストが必要な場合は、この手順を使用します。ちなみに、これはそもそもラケットの一部である必要があります。

(define (stream-take s n)
  (if (zero? n)
      '()
      (cons (stream-first s)
            (stream-take (stream-rest s) (sub1 n)))))

これで、期待どおりに機能します。

(define alt (alternate))

(stream-take alt 0)
=> '()
(stream-take alt 1)
=> '(1)
(stream-take alt 2)
=> '(1 2)
(stream-take alt 3)
=> '(1 2 1)
于 2013-02-24T22:41:52.870 に答える
1

ジェネレーターも役立つかもしれません:docs

Welcome to DrRacket, version 5.3.3.5 [3m].
Language: racket [custom].
> (require racket/generator)
> (define g (generator () (let LOOP () (yield 1) (yield 2) (LOOP))))
> (g)
1
> (g)
2
> (g)
1
> (g)
2

アップデート:

さらに良いことに、無限ジェネレータを使用します。

Welcome to DrRacket, version 5.3.3.5 [3m].
Language: racket [custom].
> (require racket/generator)
> (define g (infinite-generator (yield 1) (yield 2)))
> (g)
1
> (g)
2
> (g)
1
> (g)
2
于 2013-02-24T22:50:15.183 に答える
0

これを既存のコードの小さな変更として行う方法は次のとおりです。

(define alternate
  (letrec ([f (lambda (x) (cons x (lambda () (f (if (= x 1) 2 1)))))])
    (lambda () (f 1))))
于 2013-02-24T22:45:35.767 に答える