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