为什么 Complex 的乘法实现需要 RealFloat?
Why does the multiplication implementation for Complex require a RealFloat?
在 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
现在,为什么会这样?只是 Num a => Complex a
下的 fromInteger
有类型 RealFloat a => a -> Complex a
吗?如果是,为什么?
问题是 Complex a
仅在 a
实例化 RealFloat
时才实例化 Num
。即 Num
实例定义为:
instance RealFloat a => Num (Complex a) where
...
由于 *
由 Num
定义,如果 Complex a
是 Num
的实例,则只能在 Complex a
上使用 *
,即如果 a
是 RealFloat
.
的实例
那么为什么 Num
实例有这个限制?
是因为这个方法:
abs :: a -> a
复数的绝对值可以是非整数,即使它的两个分量都是整数。例如1+1i的绝对值为√2。因此无法定义方法 abs :: Complex Integer -> Complex Integer
(至少不能以产生正确结果的方式),因此无法定义 Num (Complex Integer)
的完整实例。所以只有 RealFloat
s.
signum
方法也是如此。
在 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
现在,为什么会这样?只是 Num a => Complex a
下的 fromInteger
有类型 RealFloat a => a -> Complex a
吗?如果是,为什么?
问题是 Complex a
仅在 a
实例化 RealFloat
时才实例化 Num
。即 Num
实例定义为:
instance RealFloat a => Num (Complex a) where
...
由于 *
由 Num
定义,如果 Complex a
是 Num
的实例,则只能在 Complex a
上使用 *
,即如果 a
是 RealFloat
.
那么为什么 Num
实例有这个限制?
是因为这个方法:
abs :: a -> a
复数的绝对值可以是非整数,即使它的两个分量都是整数。例如1+1i的绝对值为√2。因此无法定义方法 abs :: Complex Integer -> Complex Integer
(至少不能以产生正确结果的方式),因此无法定义 Num (Complex Integer)
的完整实例。所以只有 RealFloat
s.
signum
方法也是如此。