Can someone tell me why the Haskell Prelude defines two separate functions for exponentiation (i.e. ^
and **
)? I thought the type system was supposed to eliminate this kind of duplication.
Prelude> 2^2
4
Prelude> 4**0.5
2.0
There are actually three exponentiation operators: (^)
, (^^)
and (**)
. ^
is non-negative integral exponentiation, ^^
is integer exponentiation, and **
is floating-point exponentiation:
(^) :: (Num a, Integral b) => a -> b -> a
(^^) :: (Fractional a, Integral b) => a -> b -> a
(**) :: Floating a => a -> a -> a
The reason is type safety: results of numerical operations generally have the same type as the input argument(s). But you can't raise an Int
to a floating-point power and get a result of type Int
. And so the type system prevents you from doing this: (1::Int) ** 0.5
produces a type error. The same goes for (1::Int) ^^ (-1)
.
Another way to put this: Num
types are closed under ^
(they are not required to have a multiplicative inverse), Fractional
types are closed under ^^
, Floating
types are closed under **
. Since there is no Fractional
instance for Int
, you can't raise it to a negative power.
Ideally, the second argument of ^
would be statically constrained to be non-negative (currently, 1 ^ (-2)
throws a run-time exception). But there is no type for natural numbers in the Prelude
.