Does the code below overload the operators from the Prelude Num and Fractional classes? It seems to me that is not possible to overload an operation in a class other than where the signature of the operation first appeared.
Yes. You defined functions like (+)
, (-)
, and sqrt
with the same name as in the Prelude
. You imported the Prelude
as qualified
. This means that if you use 2 + 3
, it will make use of the (+)
function defined in the Number
typeclass. If you want to refer to the one in the Prelude
, you thus use (P.+)
, so x P.+ y
.
Operators are just like functions, so x + y
is syntactical sugar for (+) x y
. It thus will follow the same rules to resolve a function name like sqrt
. Since Prelude
is a qualified
import, this means that if you write sqrt
, it will look for items in the scope, and the one defined in the Number
typeclass is the only one in scope.
If you did not make a qualified
import, you will need to use (Numbers.+)
and (P.+)
to disambiguate between the two. Or if you implement this without an explicit import of the Prelude
with:
module Numbers where
class Number a where
(+), (-), (*) :: a -> a -> a
sqr, sqrt:: a -> a
instance Number Prelude.Float where
(+) a b = a Prelude.+ b
(-) a b = a Prelude.- b
(*) a b = a Prelude.* b
sqrt a = Prelude.sqrt a
sqr a = a Prelude.* a
and thus disambiguate when you use these:
ghci> 1 Prelude.+ 2
3
ghci> 1 Numbers.+ 2 :: Float
3.0
Except for the unary minus, there are thus no "builtin" operators. You can shadow any operator.