Вот что здесь происходит. Когда GH C пытается проверить тип выражения:
goodPlus (Lit (1 :: Float)) (Lit 1)
с подписью:
goodPlus :: Typed (Plus a b) => a -> b -> Plus a b
, это приводит к равенствам / ограничениям типа:
a ~ Lit Float
b ~ Lit n
Num n
Typed (Plus (Lit Float) (Lit n))
Чтобы решить это ограничение Typed
, GH C сопоставляет его с:
instance T a' ~ T b' => Typed (Plus a' b')
с:
a' ~ Lit Float
b' ~ Lit n
(Напомним, что ограничения в определениях экземпляров не играют никакой роли в сопоставлении процесс, поэтому нет проблем с соответствием этому экземпляру.) Это приводит к дополнительному ограничению:
T (Lit Float) ~ T (Lit n) -- (*)
Однако T
- это семейство связанных типов, а экземпляр для Typed (Lit a'')
специализируется на Typed (Lit Float)
и Typed (Lit n)
позволяют GH C разрешать следующие функции типа:
T (Lit Float) ~ Float
T (Lit n) ~ n
Но это вместе с (*) выше позволяет GH C сделать заключение Float ~ n
.
Итак, окончательный набор:
goodPlus (Lit (1 :: Float)) (Lit 1) :: Plus (Lit Float) (Lit Float)
и нет никакой двусмысленности.