为什么Complex的乘法实现需要一个RealFloat?

时间:2018-06-02 15:15:44

标签: haskell complex-numbers

在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吗?如果是这样,为什么?

1 个答案:

答案 0 :(得分:6)

问题是如果Complex a实例化Numa仅实例化RealFloat。这就是Num实例定义为:

instance RealFloat a => Num (Complex a) where
    ...

由于*Num定义,如果它是*的实例,您只能在Complex a上使用Num,即aRealFloat的实例。

那么为什么Num实例有这种限制?

这是因为这种方法:

abs :: a -> a

复数的绝对值即使其成分都是整数,也可以是非整数。例如,1 + 1i的绝对值是√2。因此无法定义方法abs :: Complex Integer -> Complex Integer(至少不能以产生正确结果的方式),因此不能定义Num (Complex Integer)的完整实例。所以RealFloat只有一个。

signum方法也是如此。