
G'day all. One more thing, a quick comment on Haskell style. I wrote:
sqRoot n scale = sqRoot' (5*n) 5 where sqRoot' a b | b >= invScale = div b 10 | a >= b = sqRoot' (a-b) (b+10) | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) invScale = 10^scale
In this kind of algorithm, you are almost always better off decoupling the end-of-loop test from the main computation stuff: sqRoot n scale = findEnd (sqRoot' (5*n) 5) where findEnd ((a,b):rest) | b >= 10^scale = b `div` 10 | otherwise = findEnd rest -- Rewrote this a bit. I don't like the "case" sqRoot' a b = (a,b) : case () of _ | a >= b -> sqRoot' (a - b) (b + 10) otherwise -> let (q,r) = b `divMod` 10 in sqRoot' (a * 100) (100 * q + r) There are several reasons why this is better. The main one is testability. You have, in your specification, an execution trace of the algorithm on some sample data. Use it. A second reason is because you would have tracked down your type error quicker, because it would only have been in one of these functions. A third reason is that there are circumstances where you might like to change termination conditions. This is especially true in this sort of numeric iterate-to-fixpoint algorithm. For more information, see: http://www.haskell.org/haskellwiki/Data_structures_not_functions Cheers, Andrew Bromage