[Haskell-cafe] Type conversion problems
Glynn Clements
glynn.clements at virgin.net
Sun Jun 13 06:44:38 EDT 2004
Christian Hofer wrote:
> Here is the part of my code that is troubling me:
>
> fac :: Integer -> Integer
> fac n = product [1..n]
>
> term :: Double -> Integer -> Double
> term x n = (-1.0::Double)**(fromInteger n) * (x**(fromInteger (2*n +
> 1))) /
> (fromInteger (fac (2*n + 1)))
>
> The term function is supposed to be the direct translation of the
> formula of a term within the sum. But it isn't: it is actually
> cluttered with lots of type conversions, and I had a hard time figuring
> out how to make it work at all. I hope that this is not the easiest way
> to do that and I would appreciate any help on how to handle those type
> conversion issues...
> term :: Double -> Integer -> Double
> term x n = (-1.0::Double)**(fromInteger n) * (x**(fromInteger (2*n +
> 1))) /
> (fromInteger (fac (2*n + 1)))
In this specific instance, you probably want ^ (or possibly ^^)
instead of **; these have types:
(^) :: (Num a, Integral b) => a -> b -> a
(^^) :: (Fractional a, Integral b) => a -> b -> a
The difference is that ^^ supports negative exponents.
Using ^, term can be simplified to:
term :: Double -> Integer -> Double
term x n = (-1.0)^n * x^(2*n + 1) / fromInteger (fac (2*n + 1))
You can't get rid of the conversion in the denominator, because fac
returns an integer but / isn't defined on integers.
More generally, the core arithmetic operators (+,-,*,/) all require
that both arguments have the same type, and Haskell doesn't perform
implicit type conversions.
One option is to declare your own operators, e.g.:
(!+), (!-), (!*), (!/) :: (Real a, Real b, Fractional c) => a -> b -> c
a !+ b = realToFrac a + realToFrac b
a !- b = realToFrac a - realToFrac b
a !* b = realToFrac a * realToFrac b
a !/ b = realToFrac a / realToFrac b
Each arguments can be any instance of Real (i.e. any of the built-in
numeric types except for Complex), and the result will be
automatically cast to any instance of Fractional.
However, in practice you may end up getting a lot of errors due to
ambiguous types for intermediate results, so it might be better to
force the return type to e.g. Double.
--
Glynn Clements <glynn.clements at virgin.net>
More information about the Haskell-Cafe
mailing list