再帰を使用すると、プロセスを英語でどのように説明するかを考える価値があることがよくあります。これは、多くの場合、あまり複雑にならずにコードに変換されるためです。そう...
「整数のリストの合計を再帰的に計算するにはどうすればよいですか?」
「さて、リストの合計は3 :: restOfList
?
「なにrestOfList
?
「それは何でもかまいません。しかし、覚えておいてください。私たちは再帰的です。そして、リストの合計を計算する関数を持っていませんか?」
「そうそう! では、合計は3 + sum(restOfList)
.
「そのとおりです。しかし、唯一の問題は、すべての合計が の別の呼び出しに関して定義されているsum()
ため、実際の値を取得できないことです。すべてが実際に到達する何らかの基本ケースが必要になります。 、そしてあなたが値を提供できること。」
「うーん、あなたは正しいです。」 考える...
「そうですね、あなたのリストはどんどん短くなっていきますが、可能な限り短いリストは何ですか?」
「空のリスト?」
「そうです! では、int の空のリストの合計は?」
「ゼロ - 今わかりました。まとめると、空のリストの合計はゼロであり、他のリストの合計は、残りのリストの合計に追加された最初の要素です。
実際、コードは最後の文とほぼ同じように読むことができます。
def sumList(xs: List[Int]) = {
if (xs.isEmpty) 0
else xs.head + sumList(xs.tail)
}
(Kim Stebel によって提案されたようなパターン マッチング バージョンは、本質的にこれと同じであり、より「機能的な」方法で条件を表現するだけです。)