mlyamasov, это родственник abs из мира комплексных чисел:
That is, abs z is a number with the magnitude of z, but oriented in the positive real direction, whereas signum z has the phase of z, but unit magnitude.
Дело в том, что ее присутствие в классе Num усложняет определение экземпляров класса, а практической пользы от ее наличия я не вижу. Зачастую она вообще не имеет смысла. Пример из Real World Haskell:
data Op = Plus | Minus | Mul | Div | Pow
deriving (Eq, Show)
{- The core symbolic manipulation type -}
data SymbolicManip a =
Number a -- Simple number, such as 5
| Arith Op (SymbolicManip a) (SymbolicManip a)
deriving (Eq, Show)
{- SymbolicManip will be an instance of Num. Define how the Num
operations are handled over a SymbolicManip. This will implement things
like (+) for SymbolicManip. -}
instance Num a => Num (SymbolicManip a) where
a + b = Arith Plus a b
a - b = Arith Minus a b
a * b = Arith Mul a b
negate a = Arith Mul (Number (-1)) a
abs a = error "abs is unimplemented"
signum _ = error "signum is unimplemented"
fromInteger i = Number (fromInteger i)
Согласен с Максимом. Вы же не пытаетесь избавится от других функций, напр., от синуса?
Реализация очень простая: свести диапазон чисел к трём простым: -1, 0 и 1. Один из примеров: раньше был оператор арифметической развилки (сейчас обычно используют логическую с двумя ветками) с тремя ветками. До сих пор флаги результатов операций процессора это учитывают.
Это относится только к действительным числам. Случай Complex Double уже поинтереснее. А вообще, Num --- это очень универсальная штука, например, операторы (+), (-), (*) можно использовать для работы с матрицами.
Но стоит ли овчинка выделки? Зачем усложнять класс Num? Я не могу вспомнить примеры практического применения функции signum.