cf. http://hpcgi2.nifty.com/1to100pen/wiki/wiki.cgi?p=%CB%E8%C6%FCHaskell 2006-05-21
最近流行りの SICP の 1.1.7 Newton法からお題を拝借。
おわっと,流行だったのか。もしかして乗り遅れた?
上の [1..100]>>=pen さんのもそうだし,hasko さんとこ(id:hasko:20060520:1148133213)のコメントにもあるように,先に予測値のリストを作ってしまうことにしよう。
guess x = iterate (\g -> (g + x/g) / 2.0) 1.0 goodEnough eps old new = abs (1.0 - old/new) < eps find2 f i (x:xs) | f i x = x | otherwise = find2 f x xs squareRoot x = find2 (goodEnough 0.0001) x (guess x)
guess で予測値のリストを作って,goodEnough で判定。判定は新旧予測値の比を利用し,引数で指定できるようにした。 で,あとは適当な値をリストから探すだけなんだけど,ちょうどいい関数が見あたらなかったので find2 を定義してみた。 結果。
*Main> squareRoot 4 2.000000000000002 *Main> squareRoot 1.0e-6 1.0000000000000117e-3 *Main> squareRoot 1.0e29 3.162277660171076e14 *Main> (squareRoot 1.0e-6) ^ 2 1.0000000000000235e-6 *Main> (squareRoot 1.0e29) ^ 2 1.0000000000017057e29
ふむ,よさげ。