SOE ex.11.4
(^!) :: Integer -> Integer -> Integer
x ^! n | n < 0 = error "negative exponent"
| otherwise = f x n
where
f x n | n == 0 = 1
| even n = even_f x n
| otherwise = x * even_f x (n-1)
where
even_f x n = f (x * x) (n `quot` 2)