Как выглядит тип `([] ==) []` inferred haskell?
Звучит глупо, но я не могу это понять. Почему может быть введено выражение [] == []? Более конкретно, какой тип (в классе Eq) выводится на тип элементов списка?
В сеансе ghci я вижу следующее:
Prelude> :t (==[])
(==[]) :: (Eq [a]) => [a] -> Bool
Но ограничение Eq [a]
также подразумевает Eq a
, как показано здесь:
Prelude> (==[]) ([]::[IO ()])
<interactive>:1:1:
No instance for (Eq (IO ()))
arising from use of `==' at <interactive>:1:1-2
Probable fix: add an instance declaration for (Eq (IO ()))
In the definition of `it': it = (== []) ([] :: [IO ()])
Таким образом, в [] == [] средство проверки типов должно предполагать, что элемент списка представляет собой некоторый тип a, который находится в классе Eq. Но какой? Тип [] - это просто [a], и это, безусловно, более общее, чем Eq a = > [a].
ИМХО это должно быть двусмысленным, по крайней мере в Haskell 98 (о чем мы говорим)
Ответы
Ответ 1
GHCi имеет расширенные правила для дефолта типа,, что и сработало. В этом случае я считаю, что для него будет задан двусмысленный тип ()
. Тонкие способы поведения GHCi по-разному приятны ради лучшей интерактивности, но иногда они приводят к путанице...
Ответ 2
GHC описывает наиболее общий тип:
(== []):: (Eq a) = > [a] → Bool
Его следует читать как:
- Если у вас есть экземпляр Eq a,
- тогда Haskell может дать вам функцию из списков этих "a to Bool
Итак, да, здесь подразумевается, что у вас есть экземпляр Eq для элементов списка, а GHC уже имеет экземпляр для списков вообще (полагаясь на Eq для элементов), поэтому мы получаем хороший общий тип.
Проверка типа "предполагает" вы можете предоставить экземпляр Eq при вызове определенного типа.
Я не могу воспроизвести ваши результаты ограничения Eq [a]
.