Я вникал в мельчайшие детали системы типов haskell и пытался разобраться в тонкостях классов типов. Я изучил кучу, но я натыкаюсь на стену на следующих фрагментах кода.
Используя эти определения класса и экземпляра:
class Show a => C a where
f :: Int -> a
instance C Integer where
f x = 1
instance C Char where
f x = if x < 10 then 'c' else 'd'
Почему это проходит проверку типов:
g :: C a => a -> Int -> a
g x y = f y
yes :: C a => a -> Int -> String
yes x y = show (g x y)
но это не так?
g :: C a => a -> Int -> String
g x y = show(f y)
Я нахожу второй вариант гораздо более читабельным, и это, кажется, лишь незначительное отличие (обратите внимание на сигнатуры типов). Однако попытка пройти через проверку типов приводит к следующему:
*Main> :l typetests.hs
[1 of 1] Compiling Main ( typetests.hs, interpreted )
typetests.hs:11:14:
Ambiguous type variable `a0' in the constraints:
(C a0) arising from a use of `f' at typetests.hs:11:14
(Show a0) arising from a use of `show' at typetests.hs:11:9-12
Probable fix: add a type signature that fixes these type variable(s)
In the first argument of `show', namely `(f y)'
In the expression: show (f y)
In an equation for `g': g x y = show (f y)
Failed, modules loaded: none.
И я не понимаю, почему.
Примечание. Пожалуйста, не спрашивайте: «Что вы пытаетесь сделать?» Надеюсь, очевидно, что я просто возился с абстрактным контекстом, чтобы исследовать, как работает этот язык. У меня нет другой цели, кроме изучения чего-то нового.
Спасибо