Haskell:为什么(+),(-)是Num类型类的一部分? [英] Haskell: Why is (+), (-) part of Num typeclass?

查看:63
本文介绍了Haskell:为什么(+),(-)是Num类型类的一部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自ghci:

Prelude> :i Num                              
class Num a where                            
  (+) :: a -> a -> a                         
  (-) :: a -> a -> a                         
  (*) :: a -> a -> a                         
  negate :: a -> a                           
  abs :: a -> a                              
  signum :: a -> a                           
  fromInteger :: Integer -> a                
        -- Defined in `GHC.Num'              
instance Num Word -- Defined in `GHC.Num'    
instance Num Integer -- Defined in `GHC.Num' 
instance Num Int -- Defined in `GHC.Num'     
instance Num Float -- Defined in `GHC.Float' 
instance Num Double -- Defined in `GHC.Float'

为什么(+)(-)是Num类的一部分?

Why is (+), (-) part of the Num class to begin with?

例如-您可以轻松定义此类型类:

For example - you could easily define this type class:

class Plus a where
     (+) :: a -> a -> a

然后让我们:

instance Plus [] where
    (+) = (++)

并且您也可以为集合定义这些以表示集合并集,或将(-)添加到类型类以表示集合差异...而且定义 signum毫无意义在列表上.

And you could also define these for sets to mean set union, or add (-) to a type class to mean set difference... And it makes no sense to define signum on a list.

当然我可以创建自己的使用(| + |)的类型类-但是为什么这些运算符在haskell中仅保留给Num?

Of course I could create my own type class that uses (|+|) instead - but why was these operators reserved in haskell for Num alone?

那为什么要做出这个选择?是因为遗留下来的,还是没有人想要这个?

So why was this choice made? Is it due to legacy or has no one wanted this?

推荐答案

很多是由于历史原因,但也有数学原因.例如,已经有支持二进制运算符的结构的数学名称.最常用的一个是Monoid,您可以在 Data.Monoid 中使用它.此类型类定义函数 mappend 和值 mempty ,等同于 mappend 的identity元素,并且为追加,称为<> .列表和许多其他对象形成等分体,数字实际上由 + * 组成2,其中标识元素分别为0和1.具有标识,关联二进制运算和该运算的逆运算(例如,减法是加法运算的逆运算)的结构称为组(不是标准库的一部分),并且在一个运算符和在第二个运算符下的一个monoid被称为环.这些对象是代数结构/抽象代数类的基础.

A lot of it is due to historic reasons, but there are also mathematical ones. For example, there are already mathematical names for structures that support binary operators. The most commonly used one is a Monoid, which you can use in Data.Monoid. This typeclass defines a function mappend and a value mempty, the equivalent of the identity element for mappend, and there is an operator alias for mappend called <>. Lists and many other objects form monoids, and numbers actually form 2, with + and with *, where the identity elements are 0 and 1 respectively. Structures that have an identity, an associative binary operation, and an inverse for that operation (subtraction is the inverse of addition, for example) are called groups (not part of the standard library), and structures that form a group under one operator and a monoid under a second operator are called rings. These objects are the basis for algebraic structures/abstract algebra classes.

在Haskell中实现这些数学构造有些棘手,至少非常好.对于具有 + * 的所有 Num 类型, Monoid 都有重叠的实例,对于某些数字类型,有一个如果可以定义/使得/重叠,则 Group 重叠(某些结构可以允许此定义).这些重叠的实例导致许多新类型的出现,从而使日常工作变得困难. Num 类型类在这里有帮助,因为它提供了一个有用的界面,用于操作和执行数字运算,该界面易于在现实世界的代码中使用,而不仅仅是在学术界.曾经尝试引入更多数学版本的 Prelude ,有些人使用它们的方式取得了不同的成功,但是您的普通Haskeller宁愿放弃数学的纯正度以获得更实用的界面.

These mathematical constructs are somewhat tricky to implement in Haskell, at least very well. There are overlapping instances for Monoid for all Num types with + and *, and for some numeric types there's a Group overlap if / can be defined such that dividing by 0 is well defined (some structures can allow this). These overlapping instances lead to lots of newtypes that make it difficult to work on a day to day basis. The Num typeclass helps here because it provides a useful interface, that of manipulating and performing operations on numbers, that is easy to use in real world code rather than just in academia. There have been attempts to introduce a more mathematical version of Prelude, and some people use these with varying success, but your average Haskeller would rather ditch mathematical purity for a more practical interface.

简而言之, Num 类型类的定义是出于历史原因,也是出于非常实际的原因.更加严格的数学构造是笨拙的,对于许多类型而言,只需使用 Data.Monoid <> 运算符就可以了.

In short, the Num typeclass is defined this way for historical reasons, but also for very practical reasons. A more strict mathematical construction is unwieldy, and for many types simply using Data.Monoid's <> operator is perfect.

这篇关于Haskell:为什么(+),(-)是Num类型类的一部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆