強い提案:リスト構造の設計レシピに従ってください。この問題はあなたにとって十分に目新しいものであり、簡単には理解できないでしょう。デザイン レシピの手順で実行できる追加のサポートが必要です。
この特定のケースでは、この問題の解決策がすぐに明らかではないため、役立つ一連の優れた例 (テスト ケース) が本当に必要です。この関数はリストからリストへの変換ではないため、トリッキーです。リストから数値への変換であるため、ばかげた間違いを見つけるのに役立つ強力なスイートが必要です。
たとえば、何をすべきですか?
(check-expect (reverse-list empty) <fill-me-in>)
なれ?また、空のリストも考慮する必要がありますか? 入力がおかしくないですか?それは理にかなっていますか?コントラクトは、入力として空のリストを処理する必要があると述べていますか?それとも、空でないリストのみを受け入れることを保証できますか? これは、事前に解決する必要がある種類のものです。コントラクトのタイプが原因で、現在コードにあるものは確かに正しいとは言えません...まあ、正式にコントラクトを表現していませんが、一度表現すると、基本ケースが異なる必要があることがわかりますあなたが今まで書いてきたことよりも
Design Recipe に関する引用リンクでは、パート 5 が重要です。関数のテンプレートを取得したら、自然再帰がどのようなものを計算しているかを理解する必要があります。具体的なテスト ケースを使用してください。あなたのコードを見ると、あなたが書いたコードは「自然再帰は何を計算しますか?」という質問を考慮していないように見えるため、このステップをスキップしたようです。
具体的には、次のようにします。
(reverse-list (list 1 2 3 4))
答えは何ですか?あなたはそれを自分で言いました:
(reverse-list (list 1 2 3 4)) ==> 4321
自然再帰がどうなるかを考えてみましょう:
(reverse-list (list 2 3 4))
これの価値は何ですか?私たちはそれがなければならないことを知っています
(reverse-list (list 2 3 4)) ==> 432
それを理解したら、自問してみてください: 自然再帰の値は、元の質問の答えと何らかの関係がありますか?
解決しようとしていることを考えると:
(reverse-list (list 1 2 3 4)) ===> 4321
ピース1
(リストの最初の部分) と432
(自然再帰からの) があります。まとめ1
て432
、何らかの方法で取得でき4321
ますか?
いくつかの例についてこれを繰り返します。そして、少数とは、複数を意味します。:) これらの例に対して具体的にこれを行うと、再帰ケースのコードがどうあるべきかを理解するために、パターン マッチングと一般化を行う脳がはるかにうまく機能するようになります。
つまり、具体的なケースの正しい答えを得る方法を理解するための十分な演習を行ったら、具体的な値で行っていたことをプログラムの元の用語に戻して表現できるかどうかを確認します。たとえば、次のことがわかった場合:
we want to get 4321 out of 1 and 432:
=> 1 + 10 * 432
... other examples you worked out...
これらを接頭辞表記で再表現しましょう。
we want to get 4321 out of 1 and 432:
=> (+ 1 (* 10 432))
... other examples you worked out...
どの部分が変化していますか?どの部分が同じままですか?最初の変化部分は何の略ですか?2番目の変更部分は何の略ですか? あれは:
we want to get 4321 out of 1 and 432:
=> (+ 1 (* 10 432))
... other examples you worked out ...
we want to get (reverse-list lst) out of (first lst) and (reverse-list (rest lst))
==> ???
パターンを確認したら、再帰的な場合に必要なコードを理解できたことになります。ただし、ここでは一連の例が本当に必要であることに注意してください。1 つの特定の例を一般化しようとするだけでは、脳がパターンを認識するのに十分ではありません。あなたの脳は、パターンを認識し始めるために、複数の例を繰り返し実行する必要があります。