Haskell代码是否重载Prelude的Num/Fractional类运算符?跨类重载可行吗?
问题解答
1. 这段代码没有重载Prelude中的运算符
你定义的Number是一个全新的类型类,里面的(+)、(-)、(*)、sqrt只是和Prelude里同名的操作,本质是完全独立的新定义,并非修改或重载Prelude原有的运算符。
2. 也没有重载Prelude的Num/Fractional类运算符
重载的核心是为现有类型类的操作提供新的实例实现(比如给Num类添加自定义类型的实例)。但这段代码是自己新建了Number类,然后给P.Float写了这个新类的实例,和Prelude的Num、Fractional类没有关系——你只是在实例里调用了Prelude的对应操作来实现自己类里的同名方法而已。
3. 关于“无法在操作签名首次出现的类之外重载该操作”的理解是正确的
Haskell中,每个操作(运算符或函数)的归属是其首次被声明的类型类。你不能在另一个类型类里“重载”不属于它的操作——要么为原类型类扩展实例,要么在新类里声明同名的独立操作(就像你现在做的这样),但后者不算重载,只是名字复用。
原代码回顾
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
内容的提问来源于stack exchange,提问作者Patrick Browne
相关产品推荐
相关产品推荐

