下面的代码是否重载了Prelude Num
和Fractional
类中的操作符?在我看来,除了操作签名首次出现的地方之外,不可能重载类中的操作。
我看过一个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
2条答案
按热度按时间rqcrx0a61#
下面的代码是否重载了Prelude Num和Fractional类中的运算符?在我看来,除了运算符首次出现的地方之外,不可能重载其他类中的运算符。
是。您定义了与
Prelude
中名称相同的(+)
、(-)
和sqrt
等函数。您将Prelude
导入为qualified
。这意味着如果您使用2 + 3
,它将使用Number
类型类中定义的(+)
函数。如果要引用Prelude
中的函数,则使用(P.+)
,因此x P.+ y
。操作符就像函数一样,所以
x + y
是(+) x y
的语法糖。因此,它将遵循相同的规则来解析像sqrt
这样的函数名。由于Prelude
是qualified
导入,这意味着如果您编写sqrt
,它将在作用域中查找项。并且在Number
类型类中定义的是范围中唯一的一个。如果您没有进行
qualified
导入,则需要使用(Numbers.+)
和(P.+)
来区分两者。或者,如果您在没有显式导入Prelude
的情况下使用以下命令实现此操作:从而在使用这些语句时消除歧义:
除了 unary minus之外,没有“内置”运算符。你可以隐藏任何运算符。
vsnjm48y2#
如果我们接受Bird对重载函数的定义:
那么我相信
Number
类中的(+)
、(-)
、(*)
、sqrt
、sqr
的签名和它们的示例定义不符合Bird的重载定义。考虑中缀函数
(+)
、(-)
和(*)
,它们都出现在Prelude
的Num
类中。仅关注(+)
,我们在作用域中有3个不同的名称或符号:(+)
、(P.+)
、和(Numbers.+)
都具有相同的示例定义。这与Bird中的“* 同名 ”和“ 不同的定义 *”相矛盾。sqrt
函数是Prelude
Floating
类中的一个方法。sqr
函数完全是Number
类的本地函数,它不是Prelude
中Num
类的方法。