Home > Enterprise >  Does this code overload some operators from the Prelude?
Does this code overload some operators from the Prelude?

Time:08-03

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.

  • Related