--- Square root v1
abs x | x < 0 = - x
abs x = x
improve guess x = (guess + x / guess) / 2
goodEnough guess x = Main.abs (x-guess*guess)/x < 0.00001
sqrtIter guess x = if goodEnough guess x
then guess
else sqrtIter (improve guess x) x
sqrt1 x = let guess = 1
in sqrtIter guess x
{-- To test it:
sqrt1 10
--}
--- Square root v2
sqrt2 x = let guess = 1
in sqrtIter guess x
where
sqrtIter guess x = if goodEnough guess x
then guess
else sqrtIter (improve guess x) x
improve guess x = (guess + x / guess) / 2
goodEnough guess x = Main.abs (x-guess*guess)/x < 0.00001
{-- To test it:
sqrt2 10
--}
--- Square root v3
sqrt3 x = let guess = 1
sqrtIter guess x = if goodEnough
then guess
else sqrtIter improve x
where
improve = (guess + x / guess) / 2
goodEnough = Main.abs (x-guess*guess)/x < 0.00001
in sqrtIter guess x
{-- To test it:
sqrt3 10
--}
--- Square root v4
sqrt4 x = let guess = 1
improve guess = (guess + x / guess) / 2
goodEnough guess = Main.abs (x-guess*guess)/x < 0.00001
sqrtIter guess = if goodEnough guess
then guess
else sqrtIter (improve guess)
in sqrtIter guess
{-- To test it:
sqrt4 10
--}
--- Square root v4.5
--- Does not compromise efficiency as v3, or abstraction as v4.
--- Courtesy of Jacinda Moore (originally in Oz)
sqrt4' x = let guess = 1
sqrtIter guess = if goodEnough guess
then guess
else sqrtIter (improve guess)
where improve guess = (guess + x / guess) / 2
goodEnough guess = Main.abs (x-guess*guess)/x < 0.00001
in sqrtIter guess
{-- To test it:
sqrt4' 10
--}
--- square root using Iterate abstraction
iterate' s isDone transform =
if isDone s then s
else let s1 = transform s in
iterate' s1 isDone transform
--- Square root v5
sqrt5 x = iterate' 1.0 goodEnough improve
where goodEnough = \g -> (Main.abs (x - g*g))/x < 0.00001
improve = \g -> (g + x/g)/2.0
{-- Test it with:
sqrt5 10
--}
--- Square root v6
sqrt6 x = iterate' 1
(\g -> (Main.abs (x - g*g))/x < 0.00001)
(\g -> (g + x/g)/2.0)
{-- Test it with:
sqrt6 10
--}
--- another example of using the iterate' abstraction:
factorial n = snd (iterate' (1,1)
(\(i,_) -> i>n)
(\(i,a) -> ((i+1),a*i)))
{-- Test it with:
factorial 5
--}
--- Square root v7: using infinite lists, map, compose
sqrt7 x = head (dropWhile (not . goodEnough) sqrtGuesses)
where
goodEnough guess = Main.abs (x - guess*guess)/x < 0.00001
improve guess = (guess + x/guess)/2.0
sqrtGuesses = 1:(map improve sqrtGuesses)
{-- To test it:
sqrt7 10
--}