Ответ 1
Короткий ответ
Потому что определение Num
в прелюдии:
class Num a where
...
В то время как для определения Integral
требуется, чтобы тип был Real
и Enum
:
class (Real a, Enum a) => Integral a where
...
И Real
подразумевает как Num
, так и Ord
...
class (Num a, Ord a) => Real a where
...
И Ord
, естественно, следует Eq
:
class Eq a => Ord a where
...
Эта строка означает, что для того, чтобы что-то реализовать Ord
, она должна также реализовать Eq
. Или можно сказать, что Ord
является подклассом Eq
. В любом случае...
Резюме состоит в том, что Num
не является подклассом Eq
, но Integral
является подклассом Eq
.
Длинный ответ (почему?)
Вы можете представить себе реализацию Num
способами, которые делают невозможным реализацию Eq
.
newtype Sequence = Sequence (Integer -> Integer)
instance Num Sequence where
(Sequence x) + (Sequence y) = Sequence $ \pt -> x pt + y pt
(Sequence x) - (Sequence y) = Sequence $ \pt -> x pt - y pt
(Sequence x) * (Sequence y) = Sequence $ \pt -> x pt * y pt
negate (Sequence x) = Sequence $ \pt -> -pt
abs (Sequence x) = Sequence $ \pt -> abs pt
signum (Sequence x) = Sequence $ \pt -> signum pt
fromInteger = Sequence . const
-- Ignore the fact that you'd implement these methods using Applicative.
Здесь Sequence
- это тип, представляющий все вычислимые последовательности. Вы не можете реализовать Eq
любым разумным способом, потому что последовательности бесконечно длинны!
instance Eq Sequence where
-- This will never return True, ever.
(Sequence x) == (Sequence y) =
and [x pt == y pt | pt <- [0..]] &&
and [x pt == y pt | pt <- [-1,-2..]]
Итак, имеет смысл, что Num
не является подклассом Eq
, потому что есть полезные типы, которые могут реализовать Num
, но не Eq
.