在GHCi中,人们发现以下内容:
import Data.Complex
:t 2 * (3 :+ 4)
2 * (3 :+ 4) :: RealFloat a => Complex a
:t (* (3 :+ 4))
(* (3 :+ 4)) :: RealFloat a -> Complex a -> Complex a
然而:
:t fmap (* 2) (3 :+ 4)
fmap (* 2) (3 :+ 4) :: Num a => Complex a -> Complex a
现在,为什么会这样呢?只是fromInteger
下的Num a => Complex a
类型为RealFloat a => a -> Complex a
吗?如果是这样,为什么?
答案 0 :(得分:6)
问题是如果Complex a
实例化Num
,a
仅实例化RealFloat
。这就是Num
实例定义为:
instance RealFloat a => Num (Complex a) where
...
由于*
由Num
定义,如果它是*
的实例,您只能在Complex a
上使用Num
,即a
是RealFloat
的实例。
那么为什么Num
实例有这种限制?
这是因为这种方法:
abs :: a -> a
复数的绝对值即使其成分都是整数,也可以是非整数。例如,1 + 1i的绝对值是√2。因此无法定义方法abs :: Complex Integer -> Complex Integer
(至少不能以产生正确结果的方式),因此不能定义Num (Complex Integer)
的完整实例。所以RealFloat
只有一个。
signum
方法也是如此。