Обратите внимание, что +
- это не столько оператор , сколько функция , которая по умолчанию использует инфиксное позиционирование. Это означает, что он подчиняется тем же правилам области видимости, что и все другие функции, и тому же поведению с классами типов.
В частности, класс типов определяет ряд функций, которые полиморфны для всех типов, которые создают этот конкретный класс типов. Итак, учитывая определение Num
как:
class (Eq a, Show a) => Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
мы можем сделать вывод, что все, что включает в себя определение Num
в своей области действия - например, все, что импортирует Prelude
без квалификации или исключения Num
- уже будет иметь определение в области действия для функции (+)
; которая представляет собой обычную функцию с сигнатурой типа a -> a -> a
и синтаксической склонностью к сахару, предполагаемой инфиксной, так что вы должны написать x + y
вместо + x y
.
В частности, все это означает, что точно так же, как fmap
не может быть функцией, определяемой как классом типов Functor
, так и некоторым другим классом типов, вы также не можете определять +
как Num
и другим классом типов.
Если вы хотите определить его в другом месте, вы всегда можете импортировать соответствующий квалифицированный модуль - однако имена неалфавитных функций, которые по умолчанию инфицированы, также оказываются действительно неуклюжими, когда вы импортируете их квалифицированными. В итоге вы бы написали что-то вроде 3 M.+ 4
вместо 3+4
.