The issue here, I guess, is that this behavior is inconsistent.
While the default implementation for (**) would produce NaNs and such, the implementation for Float and Double overrides this behavior:
> (-3 :: Float) ** (-5)
-4.115226e-3
> (-3 :: Double) ** (-5)
-4.11522633744856e-3
Which is in accordance to what other languages such as C and Python do (and also to what I would expect):
C
float b = -3.0;
float e = -5.0;
printf("%f\n", powf(b, e));
-0.004115
python
>>> -3.0 ** -5.0
-0.00411522633744856
The Haskell Report is not clear (or at least I was not able to find a clearer explanation) about this:
6.4.3 Exponentiation and Logarithms
The one-argument exponential function exp and the logarithm function log act on floating-point numbers and use base e. logBase a x returns the logarithm of x in base a. sqrt returns the principal square root of a floating-point number. There are three two-argument exponentiation operations: (^) raises any number to a nonnegative integer power, (^^) raises a fractional number to any integer power, and (⋆⋆)takes two floating-point arguments. The value of x^0 or x^^0 is 1 for any x, including zero; 0⋆⋆y is 1 if y is 1, and 0 otherwise.
Regards,
Emilio