Нюансы системы типов Haskell

Я разбирался в мельчайших деталях системы типов 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)

Я нахожу второе изменение native намного более читабелен, и это, кажется, лишь незначительная разница (обратите внимание на сигнатуры типов). Однако попытка пройти это мимо проверки типов приводит к:

*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.

И я не понимаю почему.

Примечание: пожалуйста, не спрашивайте «Что вы пытаетесь сделать?» Я надеюсь, что очевидно, что я просто бездельничаю в абстрактном контексте, чтобы исследовать, как работает этот язык. У меня нет другой цели, кроме как узнать что-то новое.

Спасибо

12
задан Vincent Savard 16 August 2011 в 06:24
поделиться