nRaizes :: Floating a => a -> a -> a -> a
nRaizes a b c = let r = b^2 - 4 * a * c
in if r < 0
then 0
else if r == 0
then 1
else 2
So I got this code, where I'm checking for the number of roots of an equation. But when I try to compile it, it gives me this.
Could not deduce (Ord a) arising from a use of ‘<’
from the context (Floating a)
bound by the type signature for
nRaizes :: Floating a => a -> a -> a -> a
at Ficha1.hs:29:14-43
Possible fix:
add (Ord a) to the context of
the type signature for nRaizes :: Floating a => a -> a -> a -> a
In the expression: r < 0
In the expression: if r < 0 then 0 else if r == 0 then 1 else 2
In the expression:
let r = b ^ 2 - 4 * a * c
in if r < 0 then 0 else if r == 0 then 1 else 2
Ficha1.hs:33:32:
Could not deduce (Eq a) arising from a use of ‘==’
from the context (Floating a)
bound by the type signature for
nRaizes :: Floating a => a -> a -> a -> a
at Ficha1.hs:29:14-43
Possible fix:
add (Eq a) to the context of
the type signature for nRaizes :: Floating a => a -> a -> a -> a
In the expression: r == 0
In the expression: if r == 0 then 1 else 2
In the expression: if r < 0 then 0 else if r == 0 then 1 else 2
Yes, I'm a begginer. I seriously cannot even understand what is wrong. It's a floating number, why can't it compare it? I just know it has something to do with the signature, because if I remove it it works
It's a floating number, why can't it compare it?
No, it is not per se a floating point number. Floating
strictly speaking means that you can perform trigometric and hyperbolic functions on it. Whether that means it is a floating point number, is a different aspect (although it is a bit related).
That being said, it thus does not imply that you can compare two elements. This is however not a problem: we can add the typeclass Ord a
to it:
nRaizes :: (Floating a, Ord a) => a -> a -> a -> a
nRaizes a b c = let r = b^2 - 4 * a * c
in if r < 0
then 0
else
if r == 0
then 1
else 2
But we defined our function too strict. Why do we need trigometric and hyperbolic functions here? Why not define the function over *all possible number representation with Ord
? We can thus generalize the function to:
nRaizes :: (Num a, Ord a) => a -> a -> a -> a
nRaizes a b c = let r = b^2 - 4 * a * c
in if r < 0
then 0
else
if r == 0
then 1
else 2
Furthermore, although most people like Christmas. Most programmers do not like Christmas-trees as function definitions. Perhaps a more elegant way to do this is with guards instead of if
-then
-else
s:
nRaizes :: (Num a, Ord a) => a -> a -> a -> a
nRaizes a b c | r < 0 = 0
| r == 0 = 1
| otherwise = 2
where r = b*b - 4*a*c
Finally we produce three possible outputs: 0
, 1
, and 2
. But nothing says that the type of output should be the same as the type of a
, b
and c
. So we can split the type of input and output into:
nRaizes :: (Num a, Ord a, Num b) => a -> a -> a -> b
nRaizes a b c | r < 0 = 0
| r == 0 = 1
| otherwise = 2
where r = b*b - 4*a*c
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With