
Eoin C. Bairéad wrote:
Example 2
Prelude> let fac n = if n == 0 then 1 else n * fac (n-1)
How does it know to stop ?
Becuase you said "if n == 0 then 1". In other words, if n is zero then return one and stop. Only if n does *not* equal zero does it recursively so "n * fac (n-1)".
and why does fac 2.5 hang?
Because the n == 0 condition never holds. fac 3 yields n=3, n=2, n=1, n=0, stop. fac 2.5 yeilds n=2.5, n=1.5, n=0.5, n=-0.5, n=-1.5... forever. Note carefully that fac (-6) also loops forever. Now, if you were to change the condition to "n < 1" rather than "n == 0" then it would halt in all circumstances. You could also use a type signature to state that fac accepts only whole numbers, since this function only gives a meaningful answer in that case. (If you wanted a mathematically correct function, you need the Gamma function. But that's scary stuff, and this is a Haskell lesson not an advanced math lesson.)