を記録しました。私はそれが何をしているのか見ていますが、再帰を少し簡略化することができます。読むのが楽になるかもしれませんが、ここでは52枚のカードについて話しています。:)
内側のループと外側のループは、元のコードに絡まっています。
(define (show-deck1 first-list second-list)
(define (outer-loop first-list second-list)
(cond
((null? first-list)
'())
(else
(append (inner-loop (car first-list) second-list)
(outer-loop (cdr first-list) second-list)))))
(define (inner-loop x second-list)
(cond
((null? second-list)
'())
(else
(cons (cons x (car second-list))
(inner-loop x (cdr second-list))))))
(outer-loop first-list second-list))
我々は簡素化を適用することができます:ここではそれらをdisentanglesバージョンは1つの定義がこのように表現して、それはmap
がinner-loop
を行うために使用できることを確認するために簡単です。
(define (show-deck2 first-list second-list)
(cond
((null? first-list)
'())
(else
(define x (car first-list))
(append (map (lambda (y) (cons x y)) second-list)
(show-deck2 (cdr first-list) second-list)))))
これにより、外側の繰り返しの構造がわかりやすくなります。私たちは、map
さらに一歩取り、両方の内側と外側のloopingsのためにそれを使用し、map
のネストされた使用により導入された下部を平らにする(apply append ...)
を使用することができます。
(define (show-deck3 first-list second-list)
(apply append
(map (lambda (x)
(map (lambda (y) (cons x y)) second-list))
first-list)))
バージョンが巧みで完全(apply append ...)
ものを避けます計算をスレッド化していますが、読みやすさを犠牲にしています。 (apply append ...)
を避け、まだ簡単にネストされたループ構造を見ての利点はfoldr
アプローチではなく、map
アプローチを使用することで取得するための一つの方法:
(define (foldr f acc l)
(cond
((null? l) acc)
(else
(f (car l)
(foldr f acc (cdr l))))))
(define (show-deck first-list second-list)
(foldr (lambda (x acc)
(foldr (lambda (y acc)
(cons (cons x y) acc))
acc
second-list))
'()
first-list))
これはあなたの元のコードは、前にやったことと一致する必要があります。しかし、ループの度合いはfoldr
になります。そのため、iter
の関数はすべてfoldr
の使用に消えます。
個人的に、私が完全なラケットを書いているならば、私はちょうどfor
ループでそれをコードしたいと思います。 :)これは次のようになります:
;; If we're allowed to use full Racket:
(define (show-deck first-list second-list)
(for*/list ([x first-list]
[y second-list])
(cons x y)))
多分もっと難しいスキームの変形で書くべきです。ラケットはかなり異なっています。私は個人的には「もしかしたら」が好きではない。私はプログラム全体を読んで理解することができます。 –