I defined the custom exponentiation exp' function in GHCi as:
let exp' x = sum $ take 100 [(x**k) / factorial k | k <- [0..]]
which yields the following type signature:
#> :t exp'
exp' :: (Enum a, Floating a) => a -> a
However, I would have expected it to match that of the exp function, i.e.
#> :t exp
exp :: Floating a => a -> a
Can anybody explain the Enum a => a type constraint of my exp' function? Why isn't it just Floating a => a?
Thanks.
It originates from the k <- [0..] - that desugars to use the Enum class.
It then propagates into the final type signature because you're using (**) for exponentiation which expects its arguments to be the same type:
(**) :: Floating a => a -> a -> a
One option is to use (^) for exponentiation instead:
(^) :: (Integral b, Num a) => a -> b -> a
You'll also need to convert factorial k to the right type, with something like fromIntegral:
exp' x = sum $ take 100 [(x^k) / fromIntegral (factorial k) | k <- [0..]]
It's possibly a better fit for this case because your exponents will be integers, although it may be a bit less efficient as it uses repeated multiplication (logarithmic in the exponent) rather than constant-time floating point operations.
Alternatively (as suggested in a comment), to stick with (**), use fromIntegral to move from an enumeration over Int to the actual type you are working with:
let exp' x = sum $ take 100 [(x**fromIntegral k) / fromIntegral (factorial k)
| k <- [0..]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With