Подпись типа Hugs содержит дополнительные ограничения типа? - PullRequest
5 голосов
/ 03 ноября 2011

наткнулся на это во время игры с Хаскеллом и я в тупике:

Hugs> :type (\x -> x^2)
\x -> x ^ 2 :: (Integral a, Num b) => b -> b

Что a делает там? Как я должен это читать? Если я введу то же самое в GHCi, то получится вывод, который я ожидал:

Prelude> :type (\x -> x^2)
(\x -> x^2) :: Num a => a -> a

Это ошибка в Hugs?

Ответы [ 2 ]

7 голосов
/ 03 ноября 2011

Ограничение Integral происходит из показателя степени 2. Помните, что в Haskell целочисленные литералы на самом деле являются полиморфными значениями типа Num a => a. Затем компилятор делает вывод, что, поскольку он используется в качестве показателя степени для (^) :: (Num a, Integral b) => a -> b -> a, он должен иметь более ограниченный тип Integral a => a.

Чтобы избавить вас от необходимости устранять неоднозначность числовых литералов по всему коду, Haskell использует тип по умолчанию , чтобы выбрать приемлемый конкретный тип для любых неограниченных числовых типов. В этом случае это будет Integer. Разница, по-видимому, заключается в том, что :type в Hugs сообщает о предполагаемом типе до того, как это произойдет, в то время как GHCi сообщает о типе после применения значения по умолчанию.

Если вы укажете конкретный тип для показателя степени самостоятельно, дополнительное ограничение исчезнет.

Hugs> :type (\x -> x^(2 :: Integer))
\x -> x ^ 2 :: Num a => a -> a
3 голосов
/ 03 ноября 2011

Это своего рода предположение, но это может иметь отношение к типу (^).:t (^) в ghci возвращает (^) :: (Num a, Integral b) => a -> b -> a.Я предполагаю, что hugs видит, что второй аргумент ^ должен быть Integral, и хотя этот аргумент является просто константой 2, он включает ограничение в сигнатуру типа.

...