Подтвердить что ты не робот

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?

4b9b3361

Ответ 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"