Why in Haskell 0^0 == 1 ? Why not 0^0 == 0? Or maybe should raise some error...
*Main> 0^0
1
*Main> 0**0
1.0
Thanks on advance
GHCi, version 7.10.3
Why in Haskell 0^0 == 1 ? Why not 0^0 == 0? Or maybe should raise some error...
*Main> 0^0
1
*Main> 0**0
1.0
Thanks on advance
GHCi, version 7.10.3
It makes a bit of sense when you look at the signatures.
(^) :: (Num a, Integral b) => a -> b -> a
This one is designed to work for nonnegative integer exponents. It's likely implemented recursively, so it behaves like repeated multiplication. Thus, it makes sense that "anything to the zero power is one" is the rule that takes precedent, since we're really talking about repeated multiplication.
(^^) :: (Fractional a, Integral b) => a -> b -> a
This one is a lot like the previous one, except that it works on negative exponents too, since its base is fractional. Still, it behaves like repeated multiplication or repeated division (if the exponent is positive or negative, respectively), so again, it makes sense that repeating either of those operations zero times should result in 1
, the multiplicative identity.
(**) :: Floating a => a -> a -> a
In Haskell, the floating point types generally conform to the IEEE standard, and IEEE specifically defines pow(0.0, 0.0)
as 1.0
. So Haskell, I imagine, is simply conforming to a standard so that it behaves consistently with other languages in this case.
Haskell does it that way because mathematics defines it that way. Math does it that way because 0⁰ = 1·0⁰, which is 1 multiplied by something else zero times, which is 1 not multiplied by anything. Mathematicians figure it makes more sense to stick to the rule that anything to the zeroth power is 1 (the nullary product) than the rule that zero to any power is zero.
This makes a lot of sense when you try to define exponents in terms of multiplications and divisions. For example, if you were trying to define ^
in Haskell, you might come up with:
(^) a b = product $ replicate b a
This is equivalent to:
(^) a b = foldr (*) 1 (replicate b a)
A list containing zero numbers is empty. The product of an empty list is 1, or else a lot of things would break, like product (xs++[])
not being equal to (product xs) * (product [])
.
Or if you wrote the simplest possible recursive solution:
(^) _ 0 = 1
(^) a b = a*(a^(b-1))
You would then need a special case in addition to the base and recursive cases to define 0⁰ as anthing other than 1.
As @leftroundabout points out, my answer assumes we’re using discrete math. Computer scientists almost always are, and Haskell was designed by academic computer scientists.
If we are working with continuous functions on a computer, we’re necessarily doing numeric approximations. In that case, the most efficient implementation will be the one that uses the FPU of the machine we’re running on. In 2017, that will follow the IEEE standard, which says that pow( 0.0, 0.0 ) = 1.0.
It’s just slightly simpler to write and prove statements about an exponent function that follows the convention.
Haskell is functional programming language. Functional languages use λ-calculus in their basis. Number literals are encoded using Church encoding in λ-calculus. So if you encode 0^0
by Church and then normalize λ-term using β-reductions you will get 1
like this:
0^0 = (λn.λm.λs.λz.m n s z) (λs.λz.z) (λs.λz.z) = λs.λz.s z = 1
I think this should explain why Haskell decided to follow chosen model.
This is simply a law of mathematics. Any positive number raised to the 0 power is equal to 1. There should be no error