Какая спецификация GHC/Haskell говорит, что конструкторы свободных типов соответствуют самым правым типам?

Недавно меня застали врасплох, когда я попытался передать конструктор для типа типа * -> * -> * с одним привязанным типом var функции, ожидающей конструктор для * -> *. Конкретно, это было похоже на передачу (\x -> (x, 42)) :: (forall a. a -> (a, Int)) функции типа forall c. (forall a. a -> c a) -> .... Это двусмысленно, но не является ошибкой GHC: (,), приведенное к * -> *, может быть интерпретировано как конструктор либо для левого, либо для правого аргумента, а GHC по умолчанию просто использует правый аргумент. Для совпадений более высокого типа будут использоваться наиболее правильные аргументы. Чтобы убедиться в этом, просто протестируйте предполагаемый тип:

foo :: c a b -> a -> b -> ()
foo _ _ _ = ()

bar = foo ((), 42, 'a') 42 'a' -- typechecks

Вместо этого я ошибочно полагал, что он будет соответствовать свободным переменным по порядку, но этот случай с более высоким рангом - единственный случай, когда это было бы явно предпочтительнее, а в других случаях это промывка. Есть ли официальная документация, описывающая это правило? Я немного раздражен, но также понимаю тот факт, что это не ошибка, потому что я могу предвидеть, что это экономит обертывание многих вещей в новые типы.


person concat    schedule 01.11.2019    source источник
comment
Обратите внимание, что (a,b) — это синтаксический сахар для (,) a b, а (a,b,c) — синтаксический сахар для (,,) a b c и так далее. Даже a -> b — это сокращение от (->) a b, а [a] — это сахар для [] a. Следовательно, все эти типы имеют форму T arg1 ... argn для некоторого конструктора типов T.   -  person chi    schedule 01.11.2019
comment
В частности, c является частичным применением (,,) к ().   -  person chepner    schedule 01.11.2019


Ответы (1)


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

(a, b) это (,) a b это ((,) a) b. Итак, (Int, a) — это ((,) Int) a, а (a, Int) — это не <something> a.

person Alexey Romanov    schedule 01.11.2019