民
对于数字类型,更精确地为最通用的类环 ,即数字可以相加和相减,再乘以通常意义上的,但并不一定分歧。
该类包含整数类型(Int
,Integer
,Word32
等)和分数类型(Double
,Rational
,也是复数等)。在有限类型的情况下,语义通常被理解为模运算,即具有上溢和下溢 † 。
请注意,数字类的规则严格遵守 monad 或 monoid 定律或等同比较的规则 。特别是,浮点数通常仅在近似意义上遵守法则。
方法
-
fromInteger::Num a => Integer -> a
。将整数转换为常规数字类型(如果需要,包围范围)。Haskell 数字文字可以理解为单形Integer
文字,并且围绕它进行一般转换,因此你可以在Int
上下文和Complex Double
设置中使用文字5
。 -
(+) :: Num a => a -> a -> a
。标准加法,通常被理解为联想和交换,即a + (b + c) ≡ (a + b) + c a + b ≡ b + a
-
(-) :: Num a => a -> a -> a
。减法,这是加法的倒数:(a - b) + b ≡ (a + b) - b ≡ a
-
(*) :: Num a => a -> a -> a
。乘法,一种对加法进行分配的关联运算:a * (b * c) ≡ (a * b) * c a * (b + c) ≡ a * b + a * c
对于最常见的实例,乘法也是可交换的,但这绝对不是必需的。
-
negate::Num a => a -> a
。一元否定运算符的全名。-1
是negate 1
的语法糖。-a ≡ negate a ≡ 0 - a
-
abs::Num a => a -> a
。绝对值函数总是给出相同幅度的非负结果abs (-a) ≡ abs a abs (abs a) ≡ abs a
abs a ≡ 0
应该只在a ≡ 0
发生。对于真实类型,很清楚非负面意味着什么:你总是拥有
abs a >= 0
。复杂等类型没有明确定义的排序,但是abs
的结果应该总是位于真实的子集 ‡中 (即给出一个也可以写成单个数字文字但没有否定的数字)。 -
signum::Num a => a -> a
。根据名称,sign 函数只产生-1
或1
,具体取决于参数的符号。实际上,这只适用于非零实数; 一般来说signum
更好地理解为归一化函数:abs (signum a) ≡ 1 -- unless a≡0 signum a * abs a ≡ a -- This is required to be true for all Num instances
请注意, Haskell 2010 报告的第 6.4.4 节明确要求保留任何有效的
Num
实例的最后一个等式。
有些库,特别是线性和 hmatrix ,对 Num
类的用途有一个更为宽松的理解:它们只是将算术运算符重载为一种方法。虽然这对于+
和 -
来说非常简单,但是对于*
来说已经变得很麻烦了,而其他方法则更是如此。例如, *
应该表示矩阵乘法还是逐元素乘法?
定义这样的非数字实例可能是个坏主意; 请考虑专用类,如 VectorSpace
。
† 特别是,无符号类型的负数被包裹到大的正数,例如 (-4 :: Word32) == 4294967292
。
‡ 这种情况大多没有实现:矢量类型没有真正的子集。这类有争议的 Num
-实例通常定义了 abs
和 signum
元素,从数学角度讲它们并不真正有意义。