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