2013-10-11 2 views
12

Недавно я взглянул на Haskell, используя LYAH.Haskell Почему «Num x» требует «Показать x»?

я бездельничал с классами типа и написал эту функцию быстрого тест:

foo :: (Num x) => x -> String 
foo x = show x ++ "!" 

Но что вызывает эту ошибку:

test.hs:2:9: 
    Could not deduce (Show x) arising from a use of `show' 
    from the context (Num x) 
    bound by the type signature for foo :: Num x => x -> String 
    at test.hs:1:8-29 
    Possible fix: 
     add (Show x) to the context of 
     the type signature for foo :: Num x => x -> String 

Но согласно Лях:

To join Num, a type must already be friends with Show and Eq.

Так что если все в Num является подмножеством Show и Eq, почему мне нужно изменить подпись типа на foo :: (Num x, Show x) => x -> String, чтобы это работало? Нельзя ли сделать вывод, что Num также доступен для показа?

ответ

18

Информация в LYAH устарела. release notes for GHC 7.4.1 говорят, что:

The Num class no longer has Eq or Show superclasses.

Вам нужно будет написать,

foo :: (Num x, Show x) => x -> String 

(На самом деле, foo вы писали не требует Num x, так что вы можете пропустить, что, чтобы избежать ненужных ограничений.)

+1

Итак, какие подклассы 'Num' _don't_ имеют' Eq' или 'Show' больше? Я не вижу никаких списков о том, что их получило (или почему это вообще было изменено вообще). – charmlessCoin

+6

Раньше это было 'class (Eq a, Show a) => Num a where {...}', теперь это просто 'class Num a where {...}'. Не нужно было иметь 'Eq' и' Show' в качестве суперкласса: экземпляр 'Num' не подразумевает экземпляр любого из этих классов (например,' Ord' подразумевает 'Eq') и не зависит от них ('Num' не имеет законов, и определения по умолчанию для его« методов »не относятся к« Eq »или« Show »). Я думаю, именно поэтому 'Num' стал самостоятельным классом. Меньшие требования означают, что класс допускает больше экземпляров, таких как 'Num b => Num (a -> b)'. –

+3

Важно отметить, что это изменение GHC; стандарт Haskell по-прежнему требует суперкаров «Show» и «Eq».В строгом смысле это делает GHC компилятором, не совместимым с Haskell; однако это изменение, скорее всего, вступит в следующий стандарт, так же, как скоро «Аппликативный» станет суперклассом «Монады». – David

1

Вы не должны написать:

(Num x) => x -> String 

Вместо

(Num x) x -> String 

И насколько я знаю, это наследство, по крайней мере устарели.

3

Это used to be, что экземпляр Num также экземпляр Show и Eq, но это no longer the case.

Вам также необходимо добавить ограничение Show.

3

Haskell, оба 98 и 2010 оба требуют, чтобы все экземпляры Num также были экземплярами на Show и Eq. Это во многом случай истории.

GHC, самый популярный компилятор Haskell, отклоняется от стандарта здесь, не требуя никакой прагмы. Это было сделано, чтобы аппликативные функторы были экземплярами Num и пользовались преимуществами перегруженного синтаксиса.

Смежные вопросы