module Factorial ( iterative , recursive , tailRecursive ) where

iterative :: Integer -> Integer
iterative n
    | n < 0 = error "Factorial not defined for negative integers."
    | n == 0 = 1
    | n > 0 = product [1..n]

recursive :: Integer -> Integer
recursive n
    | n < 0 = error "Factorial not defined for negative integers."
    | n == 0 = 1
    | n > 0 = n * recursive ( n - 1 )

-- iterate is a function in the standard prelude, so we cannot use that name.

tailRecursive :: Integer -> Integer
tailRecursive n
    | n < 0 = error "Factorial not defined for negative integers."
    | n == 0 = 1
    | n > 0 = iteration 1  n  1
    where iteration n max result  = if n > max then result else  iteration ( n + 1 )  max ( result * n ) 
