[Haskell-cafe] Type conversion problems
Hi, after some playing around with monad transformers and starting to like those specialities of Haskell, I am currently really feeling thrown back by a simple problem: trying to write a sine-function... 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... Thanks, Chris ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type conversion problems
On Sun, Jun 13, 2004 at 11:15:28AM +0200, Christian Hofer wrote: 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))) Why do you have all those type annotations? Simply writing directly: fac n = product [1..n] term x n = -1 ** n * (x ** (2 * n + 1)) / fac (2 * n + 1) gives you functions for which are inferred the types (which you can of course also give explicitly if you want): fac :: (Enum a, Num a) = a - a term :: (Floating a, Enum a) = a - a - a And the type variable a can then be instantiated for Double. If you really need to take an Integer parameter, you only need a single conversion: term' x n = term x (fromIntegral n) with the type: term' :: (Floating a, Enum a, Integral b) = a - b - a If all this looks confusing, then forget about polymorphism and just give exact types in the type annotations: fac :: Double - Double fac n = product [1..n] term :: Double - Double - Double term x n = -1 ** n * (x ** (2 * n + 1)) / fac (2 * n + 1) term' :: Double - Integer - Double term' x n = term x (fromIntegral n) Hope this helps. Lauri Alanko [EMAIL PROTECTED] ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type conversion problems
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 [EMAIL PROTECTED] ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type conversion problems
Am 13.06.2004 um 12:44 schrieb Glynn Clements: 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)) (Further interesting information snipped...) Ok, I just didn't know this operator. This is actually exactly what I was hoping to be able to write. Thanks, Chris ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type conversion problems
Lauri Alanko wrote: 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))) Why do you have all those type annotations? Simply writing directly: fac n = product [1..n] term x n = -1 ** n * (x ** (2 * n + 1)) / fac (2 * n + 1) gives you functions for which are inferred the types (which you can of course also give explicitly if you want): fac :: (Enum a, Num a) = a - a term :: (Floating a, Enum a) = a - a - a And the type variable a can then be instantiated for Double. Except that it's arguable that Double shouldn't be an instance of Enum. Really, this solution is relying upon a misfeature of the language; one which won't work in the general case. Suppose that fac was a different function, one which couldn't be defined as returning a non-integral result without using an explicit (and conceptually incorrect) type conversion. -- Glynn Clements [EMAIL PROTECTED] ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe