Почему Haskell по умолчанию читает Int при чтении Num? - PullRequest
8 голосов
/ 29 мая 2011

Я не ожидал, что следующий код будет работать:

foo :: (Num a) => a -> a
foo x = x + x

main = do
    print (foo (read "7"))

, потому что невозможно полностью вывести тип (прочитайте «7») на основе кода.Но GHC (6.12.3) считает иначе и печатает 14.

Если «7» изменяется на «7.2», код завершается неудачно с «без разбора».Что тут происходит?как Haskell решает, какой экземпляр Read использовать?

Ответы [ 2 ]

12 голосов
/ 29 мая 2011

Это вызвано правилами по умолчанию Haskell для Num класса . Если вы добавили

default (Double, Integer)

в начало вашего файла, тогда вы получите следующие результаты:

main = do
  print (foo (read "7")) -- prints "14.0"
  print (foo (read "7.2")) -- prints "14.2"

Короче говоря, правила по умолчанию - это попытка "попытаться сделать правильные вещи" и избавить вас от ошибки компиляции, когда в вашей программе есть неоднозначный тип. К сожалению, в этом случае он заменяет ошибку времени компиляции на ошибку времени выполнения.

Вы можете отключить настройки по умолчанию следующим образом:

default ()

, который заставит вас явно устранять неоднозначность типов таких терминов с помощью аннотаций типов:

print (foo (read "7" :: Int))
2 голосов
/ 29 мая 2011

Int является типом по умолчанию в этом случае.См. Сек6.3, Неопределенность и тип по умолчанию, в истории Haskell: быть ленивым с классом,

...