[英]Haskell: Why is (+), (-) part of Num typeclass?
來自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類的一部分?
例如 - 您可以輕松定義此類型類:
class Plus a where
(+) :: a -> a -> a
然后讓:
instance Plus [] where
(+) = (++)
你還可以為集合定義這些集合來表示集合聯合,或者將(-)
添加到類型類中以表示集合差異......並且在列表上定義signum
是沒有意義的。
當然我可以創建自己的類型使用(|+|)
代替 - 但為什么這些運算符在haskell中僅為Num保留?
那么為什么選擇這個呢? 是遺產還是沒有人想要這個?
其中很多是由於歷史原因,但也有數學原因。 例如,已經有支持二元運算符的結構的數學名稱。 最常用的是Monoid,可以在Data.Monoid
使用。 此類型類定義了一個函數mappend
和值mempty
,為標識元件的等效mappend
,並且對於操作者別名mappend
稱為<>
列表和許多其他對象形成幺半群,數字實際上形成2,帶有+
和*
,其中標識元素分別為0和1。 具有標識,關聯二元運算和該運算的逆的結構(例如,減法是加法的逆)被稱為組(不是標准庫的一部分),以及在一個運算符下形成組的結構第二個運算符下的幺半群稱為環。 這些對象是代數結構/抽象代數類的基礎。
這些數學結構在Haskell中實現起來有點棘手,至少非常好。 對於具有+
和*
所有Num
類型, Monoid
存在重疊實例,並且對於某些數字類型,如果/
可以定義Group
重疊,則將0除以得到明確定義(某些結構可以允許這樣)。 這些重疊的實例導致許多新類型,使其難以在日常工作。 Num
類型類在這里有所幫助,因為它提供了一個有用的界面,即操作和執行數字操作,這在現實世界的代碼中很容易使用,而不僅僅是在學術界。 有人嘗試引入Prelude
的更多數學版本,有些人使用它們取得了不同的成功,但是你的普通Haskeller寧願放棄數學純度以獲得更實用的界面。
簡而言之, Num
類型類由於歷史原因而以這種方式定義,但也是出於非常實際的原因。 更嚴格的數學結構是不實用的,對於許多類型而言,簡單地使用Data.Monoid
的<>
運算符是完美的。
我的猜測是他們希望Num
反映數字的數學性質,而不是一些更一般的結構。 Num
中的操作主要是那些支持稱為環的抽象數學結構的操作,其中整數(及其任何擴展)是一個突出的例子。
由於Haskell允許您定義自己的運算符,因此您可以設置自己的表示法。 然后,當其他人閱讀您的代碼時,他們將能夠告訴您正在使用不像Num
ber之類的東西,但可能更通用。
在Haskell前奏中有許多不幸的歷史設計決定,這些決定無法修復,因為它們會破壞兼容性。 但是,恕我直言, Num
類型類和運算符的基本設計是合理的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.