私の質問は、ネストされた if 条件をcond
、ローカル バインディングを持つブランチを持つ単一の条件に書き換えることについてです。私はラケットに非常に慣れていないので、最初の一歩を踏み出したばかりなので、私の質問がばかげている場合は、寛大にしてください.
簡単に言えば、このタスクは、ベクトルを取り、その中の値を検索する関数を作成することです。ベクトルには、ペアと非ペアの混合物が含まれています。関心のある値は、ペアの車にある必要があります。
実用的なソリューションでは、ネストされた if で再帰ヘルパー関数を使用します
[vlen (vector-length vec)]
[find-in-vector
(lambda (pos)
(if (= pos vlen) ;; if the end of the vector has been reached
#f ;; then return false
(let ([el (vector-ref vec pos)]) ;; Otherwise, extract current element from the vector,
(if (and (pair? el) (equal? v (car el))) ;; if the element is a pair and its car is what we want
el ;; then return the element
(find-in-vector (+ 1 pos))))))] ;; otherwise keep searching the vector
cond
よりコンパクトに見えるように書き換えたいと思います。以下のコードは可能な実装です。問題は、それ(vector-ref vec pos)
が数回計算されることです。これは、ネストされたifを使用した以前の実装のように、1回だけ計算されるように書き直したいものです
[vlen (vector-length vec)]
[find-in-vector
(lambda (pos)
(cond [(= pos vlen) #f]
[(and (pair? (vector-ref vec pos)) ;; one
(equal? v (car (vector-ref vec pos)))) ;; two
(vector-ref vec pos)] ;; three is too many
[#t (find-in-vector (+ 1 pos))]))])
そして、これが私が達成した最大のものです: (vector-ref vec pos)
test-expr での 1 つの呼び出しと、result-expr での別の呼び出し
(cond
[(= pos vlen) #f]
[(letrec ([el (vector-ref vec pos)]) ;; extract current element from the vector
(and (pair? el) (equal? v (car el)))) ;; and use it in conditionals
(vector-ref vec pos)] ;; again, extract and return. FIXIT
[#t (find-in-vector (+ 1 pos))]))]) ;; otherwise, keep searching
el
test-expr と result-expression の間でさらに共有するにはどうすればよいですか? el
そして、私はこの特定の cond-branch のローカルにとどまりたいと思っています。以下のコードは正しく動作しません。AFAIU、letrec
式全体が cond の text-expr と見なされますか?
(cond
[(= pos vlen) #f]
[(letrec ([el (vector-ref vec pos)])
(and (pair? el) (equal? v (car el)))
el)]
[#t (find-in-vector (+ 1 pos))])