对于数字类型,更精确地为最通用的类 ,即数字可以相加和相减,再乘以通常意义上的,但并不一定分歧。

该类包含整数类型(IntIntegerWord32 等)和分数类型(DoubleRational,也是复数等)。在有限类型的情况下,语义通常被理解为模运算,即具有上溢和下溢

请注意,数字类的规则严格遵守 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。一元否定运算符的全名。-1negate 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 函数只产生 -11,具体取决于参数的符号。实际上,这只适用于非零实数; 一般来说 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-实例通常定义了 abssignum 元素,从数学角度讲它们并不真正有意义。