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.
I have looked at a related question .
module Numbers where
import qualified Prelude as P
class Number a where
( ), (-), (*) :: a -> a -> a
sqr, sqrt:: a -> a
instance Number P.Float where
( ) a b = a P. b
(-) a b = a P.- b
(*) a b = a P.* b
sqrt a = P.sqrt a
sqr a = a P.* a
CodePudding user response:
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.
CodePudding user response:
If we accept Bird's definition of overloaded functions:
"Overloaded functions are functions with the same name but different definitions."
Then I believe that the signatures for ( )
, (-)
, (*)
, sqrt
, sqr
in the Number
class and their instance definitions do not fit Bird's definition of overloading.
Considering the infix functions ( )
, (-)
, and (*)
they all occur in the Num
class in the Prelude
. Focusing on just ( )
we have 3 distinct names or symbols in scope: ( )
, (P. )
, and (Numbers. )
all with the same instance definition. This contradicts "same name" and "different definitions" from Bird.
The sqrt
function is a method from the Prelude
Floating
class. The sqr
function is entirely local to the Number
class it is not a method from the Num
class in the Prelude
.