Since the roots can be complex, they can't be represented in a Float
in all cases. A possible fix is to switch the result type to involve Complex Float
, which stores both the real and imaginary part.
Below, x :+ y
stands for a complex number with real part x
and imaginary part y
.
import Data.Complex
roots :: (Float, Float, Float)
-> (Complex Float, Complex Float)
roots (a,b,c) =
let s = sqrt ((b*b - 4.0*a*c) :+ 0)
d = 2.0*a :+ 0
b' = b :+ 0
in ((-b' + s)/d, (-b' - s)/d)
Now, complex roots are printed instead of NaN
s.
> roots (1,0,1)
(0.0 :+ 1.0,(-0.0) :+ (-1.0))
(Note that if a
is zero we can still get a NaN
if we try to compute 0/0
. But that's a distinct issue.)
By the way, in Haskell we usually define functions in their curried form, i.e.
roots :: Float -> Float -> Float
-> (Complex Float, Complex Float)
roots a b c = ...