import Data.Complex
import System.IO
-- Function to calculate the solutions of the quadratic equation in the form of complex numbers.
quadraticEquation:: Float -> Float -> Float -> (Complex Float, Complex Float)
quadraticEquation a b c
| a == 0 = error "a cannot be zero"
| disc < 0 = (x1, x2)
| otherwise = (x1, x2)
where
-- We calculate the discriminant
disc = b^2 - 4*a*c
-- Calculate the solutions of the quadratic equation
x1 = (-b sqrt disc) / (2*a)
x2 = (-b - sqrt disc) / (2*a)
-- Principal fonction
main :: IO ()
main = do
-- Ask the user to enter the values of a, b and c
putStrLn "Enter the value of a:"
aStr <- getLine
putStrLn "Enter the value of b:"
bStr <- getLine
putStrLn "Enter the value of c:"
cStr <- getLine
-- Convert the values to floats
let a = read aStr :: Float
let b = read bStr :: Float
let c = read cStr :: Float
-- We calculate the solutions of the quadratic equation
let solutions = quadraticEquation a b c
-- Display the solutions on the screen
putStrLn "The solutions of the quadratic equation are:"
putStrLn (show (fst soluciones))
putStrLn (show (snd soluciones))
in visual studio code, I get an error in the last 3 lines and I don't understand.
/Users/...hs:9:17: error:
• Couldn't match expected type ‘Complex Float’
with actual type ‘Float’
• In the expression: x1
In the expression: (x1, x2)
In an equation for ‘quadraticEquation’:
quadraticEquation a b c
| a == 0 = error "a cannot be zero"
| disc < 0 = (x1, x2)
| otherwise = (x1, x2)
where
disc = b ^ 2 - 4 * a * c
x1 = (- b sqrt disc) / (2 * a)
x2 = (- b - sqrt disc) / (2 * a)
|
9 | | disc < 0 = (x1, x2)
| ^^
/Users/...hs:9:21: error:
• Couldn't match expected type ‘Complex Float’
with actual type ‘Float’
• In the expression: x2
In the expression: (x1, x2)
In an equation for ‘quadraticEquation’:
quadraticEquation a b c
| a == 0 = error "a cannot be zero"
| disc < 0 = (x1, x2)
| otherwise = (x1, x2)
where
disc = b ^ 2 - 4 * a * c
x1 = (- b sqrt disc) / (2 * a)
x2 = (- b - sqrt disc) / (2 * a)
|
9 | | disc < 0 = (x1, x2)
| ^^
/Users/...hs:10:18: error:
• Couldn't match expected type ‘Complex Float’
with actual type ‘Float’
• In the expression: x1
In the expression: (x1, x2)
In an equation for ‘quadraticEquation’:
quadraticEquation a b c
| a == 0 = error "a cannot be zero"
| disc < 0 = (x1, x2)
| otherwise = (x1, x2)
where
disc = b ^ 2 - 4 * a * c
x1 = (- b sqrt disc) / (2 * a)
x2 = (- b - sqrt disc) / (2 * a)
|
10 | | otherwise = (x1, x2)
| ^^
/Users/...hs:10:22: error:
• Couldn't match expected type ‘Complex Float’
with actual type ‘Float’
• In the expression: x2
In the expression: (x1, x2)
In an equation for ‘quadraticEquation’:
quadraticEquation a b c
| a == 0 = error "a cannot be zero"
| disc < 0 = (x1, x2)
| otherwise = (x1, x2)
where
disc = b ^ 2 - 4 * a * c
x1 = (- b sqrt disc) / (2 * a)
x2 = (- b - sqrt disc) / (2 * a)
|
10 | | otherwise = (x1, x2)
| ^^
where am I going wrong, have I saved something? I accept suggestions and correction of the code.
Thank you very much!
CodePudding user response:
Though you specified the result type to be Complex Float
, you never tell the compiler where it's supposed to switch from the real inputs (Float
) to the complex type. And Haskell never converts types implicitly.
...And this is actually a great example for why this is good: in other languages, what would happen here is that the whole calculation would be attempted in real arithmetic and only the final result converted to complex, which is of course completely missing the point!
Instead, what you want is to already compute the square roots in complex arithmetic, so that negative discriminants can be handled.
sqrt (disc : 0)
That's not sufficient to get your code to compile though, and here the flip side of no-implicit-conversions comes in: you need to convert all the real values appearing in the complex-valued expression, like
x1 = (-(b: 0) sqrt (disc: 0)) / (2*a : 0)
Alternatively, you can use the fact that the square root is always either purely-real or purely-imaginary, depending on the sign of the discriminant. Thus you can put together the x1
and x2
accordingly, without actually using any complex arithmetic.