Num vs Integral
Эта функция:
hola :: (Integral a) => a -> String
hola 1 = "OK"
hola _ = "asdf"
работает отлично. Но этот:
hola :: (Num a) => a -> String
hola 1 = "OK"
hola _ = "asdf"
не может быть скомпилирован: "Не удалось вывести (Eq a) из литерала` 1 '
Я действительно не понимаю. Я читаю учебник, где сказано
"Интеграл также является числовым классом типа. Num включает все числа, включая действительные числа и целые числа, Integral включает только целые (целые) числа. В этом классе типов есть Int и Integer." http://learnyouahaskell.com/types-and-typeclasses
Почему я не могу использовать Num?
Ответы
Ответ 1
Это недавнее изменение предложенное и принятое в сентябре/октябре прошлого года, в последней версии базового пакета Eq
и Show
больше не являются суперклассами Num
. С тех пор ни одна новая версия языкового отчета не была опубликована, поэтому еще нет в отчете. И с недавнего времени он еще не сделал это еще во многих учебниках или книгах.
"Совпадение шаблонов" с числовым литералом является неявным применением (==)
, поэтому для работы требуется экземпляр Eq
. Этот экземпляр теперь больше не может быть выведен из ограничения Num
, поэтому компилятор (совершенно новый: D) отклоняет код только с ограничением Num
.
Но Integral
является подклассом Real
, который имеет Ord
(и, следовательно, Eq
) как суперкласс, поэтому он работает.
Ответ 2
Как сказал Даниэль Фишер, он работал, но теперь он не работает, потому что Num
и Eq
были разделены, поэтому Num a
больше не подразумевает Eq a
. Чтобы исправить ваш код, просто сделайте Eq a
явным:
hola :: (Num a, Eq a) => a -> String
hola 1 = "OK"
hola _ = "asdf"