4

最近は余暇のプログラミングに Haskell を使用しています。命令型言語のプログラマーとして 8 年以上働いているので、いくつかの関数構造 (特に折り畳み) に頭を悩ませるのは難しいことです。プロジェクト Euler の問題を解決していたところ、たまたま次のコードが生成されました。

f (num, den) s | num*10 < den = s
               | otherwise = f (ratio (num, den) s') s'
               where s' = (s+2)

この明示的な再帰は、フォールドまたはその他の関数構造を使用して書き直すことができますか? 折り畳みを使用する際の主なハードルは、ステップ関数を考え出すことでした。最終的に私はあきらめ、再帰に頼りました。

編集:また、関数内の別の関数によって返された出力を、明示的な再帰なしで呼び出し元の関数への入力として作成するにはどうすればよいですか?

4

1 に答える 1

10

古き良きものは常にあるuntil

f = until test func
  where test ((a, b), _) = a * 10 < b
        func (p, s) = (ratio p s+2, s+2)

ただし、公平を期すために、実際には常に何らかの再帰が発生します。それは、それをどれだけ抽象化するかの問題です。Haskell には「ループ」はありません。

2番目の質問については、「再帰を行わずに関数呼び出し自体を行うにはどうすればよいですか」と尋ねたと思います。つまり、それが再帰の定義であるため、できません。

until iterateただし、 and (その実装を見てください) のような高階関数fixを使用すると、ワーカー関数を呼び出す必要がなくなります。彼らは隠れて明示的な再帰を処理します。

于 2013-06-16T20:16:58.270 に答える