
Hi, When compiling this: ************ import Complex; complex_root :: (Float, Float, Float) -> (Complex Float, Complex Float) complex_root (a,b,c) = (x1,x2) where { delta = b * b - 4 * a * c :: Float; sqr_delta = if delta >= 0 then (sqrt delta) :+ 0 else 0 :+ (sqrt delta) :: (Complex Float); x1 = (b + sqr_delta)/(2 * a); x2 = (b - sqr_delta)/(2 * a); } *********** I get this error message: ********** Couldn't match `Float' against `Complex Float' Expected type: Float Inferred type: Complex Float In the second argument of `(+)', namely `sqr_delta' In the definition of `x1': x1 = (b + sqr_delta) *********** Can you help me finding what is wrong? Shouldn't "b" be converted to Complex Float and be summed to sqr_delta? Thanks for your help, Maurício

On 6 Jan 2005, at 01:37, Maurício wrote:
import Complex;
complex_root :: (Float, Float, Float) -> (Complex Float, Complex Float) complex_root (a,b,c) = (x1,x2) where { delta = b * b - 4 * a * c :: Float; sqr_delta = if delta >= 0 then (sqrt delta) :+ 0 else 0 :+ (sqrt delta) :: (Complex Float); x1 = (b + sqr_delta)/(2 * a); x2 = (b - sqr_delta)/(2 * a); }
Couldn't match `Float' against `Complex Float' Expected type: Float Inferred type: Complex Float In the second argument of `(+)', namely `sqr_delta' In the definition of `x1': x1 = (b + sqr_delta)
Can you help me finding what is wrong? Shouldn't "b" be converted to Complex Float and be summed to sqr_delta?
Haskell will not automatically convert b from Float to Complex Float. The arguments of (+) should have the same type. One alternative is to use b :+ 0 instead of b. (and similarly for a). Another approach is to define a 'cast' function like: toComplex x = (fromRational.toRational) x :: Complex Float and then you can use toComplex b instead of b :+ 0. that's more characters to type, though... Note that sqr_delta isn't going to be defined as you expect, either. Since delta has type Float, sqrt delta has type Float. (And sqrt -1 :: Float is Not A Number). If you want to do it by hand this way, then you want:
sqr_delta = if delta >= 0 then (sqrt delta) :+ 0 else 0 :+ (sqrt (-delta)) :: (Complex Float);
If delta was itself already Complex, then sqrt would do the right thing automatically. Jules

Maurício
complex_root :: (Float, Float, Float) -> (Complex Float, Complex Float) complex_root (a,b,c) = (x1,x2) where { delta = b * b - 4 * a * c :: Float; sqr_delta = if delta >= 0 then (sqrt delta) :+ 0 else 0 :+ (sqrt delta) :: (Complex Float);
x1 = (b + sqr_delta)/(2 * a); x2 = (b - sqr_delta)/(2 * a); }
Couldn't match `Float' against `Complex Float' Expected type: Float Inferred type: Complex Float In the second argument of `(+)', namely `sqr_delta' In the definition of `x1': x1 = (b + sqr_delta)
The error message says it all, really. If you examine the definition of x1, you see that (+) is applied to two variables. If you check these, you will discover that they have different types, which is the cause of the error. Note that Haskell doesn't automatically convert arguments for you -- this is a feature. -kzm -- If I haven't seen further, it is by standing in the footprints of giants

Ketil Malde wrote:
Maurício
writes: (...)
Couldn't match `Float' against `Complex Float' Expected type: Float Inferred type: Complex Float In the second argument of `(+)', namely `sqr_delta' In the definition of `x1': x1 = (b + sqr_delta)
The error message says it all, really.
(...)
Note that Haskell doesn't automatically convert arguments for you -- this is a feature.
-kzm
When I type this: ***** import Complex; a = 3 :+ 4; ***** and load it into ghci, "a + 4" gives me "7.0 :+ 4.0", although "a + (4::Float)" gives me that error again. Why Haskell converts "4" to Complex but not a Float? Maurício

Maurício comments the remark of Ketil Malde
Note that Haskell doesn't automatically convert arguments for you -- this is a feature.
When I type this:
***** import Complex; a = 3 :+ 4; *****
and load it into ghci, "a + 4" gives me "7.0 :+ 4.0", although "a + (4::Float)" gives me that error again. Why Haskell converts "4" to Complex but not a Float?
You should read thoroughly the Haskell documentation. You will learn that Haskell casts EXPLICIT NUMERICAL CONSTANTS, but not variables. Actually this is not a "conversion", but an overloading of numerical constants. The lexical entity "4" behaves as "fromInteger 4", and the type checker uses the fromInteger appropriate to the context. Floating, Complex, etc. With 4.0 it will work also (overloaded fromRational). Jerzy Karczmarczuk

On Thu, 6 Jan 2005 karczma@info.unicaen.fr wrote:
Actually this is not a "conversion", but an overloading of numerical constants. The lexical entity "4" behaves as "fromInteger 4", and the type checker uses the fromInteger appropriate to the context. Floating, Complex, etc. With 4.0 it will work also (overloaded fromRational).
Though I think the syntax should distinguish between the polymorphic value '4' and the bare integer from which it is convert, say '#4', that is '4 = fromInteger #4'.

On 6 Jan 2005, at 14:06, Maurício wrote:
***** import Complex; a = 3 :+ 4; *****
and load it into ghci, "a + 4" gives me "7.0 :+ 4.0", although "a + (4::Float)" gives me that error again. Why Haskell converts "4" to Complex but not a Float?
The answer lies available to you in ghci: Prelude> :t 4 4 :: forall t. (Num t) => t The type of for is 'any type in the Num class'. So '4' stands for the Integer four as well as the Float four and the Double four and indeed the Complex 4. No conversion is actually happening. Jules

Jules Bean wrote:
(...) Why Haskell converts "4" to Complex but not a Float?
The answer lies available to you in ghci:
Prelude> :t 4 4 :: forall t. (Num t) => t
The type of for is 'any type in the Num class'. So '4' stands for the Integer four as well as the Float four and the Double four and indeed the Complex 4.
No conversion is actually happening.
Interesting. The tutorial I'm following didn't say anything about classes yet. I'll read about it and then go back to my problem. Thanks.
participants (5)
-
Henning Thielemann
-
Jules Bean
-
karczma@info.unicaen.fr
-
Ketil Malde
-
Maurício