Быстрый пример:
{-# LANGUAGE RankNTypes #-}
l :: (forall b. [b] -> [b]) -> Int
l f = 3
l1 :: forall a. a -> a
l1 x = x
l2 :: [Int] -> [Int]
l2 x = x
k :: ((forall b. [b] -> [b]) -> Int) -> Int
k f = 3
k1 :: (forall a. a -> a) -> Int
k1 x = 99
k2 :: ([Int] -> [Int]) -> Int
k2 x = 1000
m :: (((forall b. [b] -> [b]) -> Int) -> Int) -> Int
m f = 3
m1 :: ((forall a. a -> a) -> Int) -> Int
m1 x = 99
m2 :: (([Int] -> [Int]) -> Int) -> Int
m2 x = 1000
Здесь:
l l1
проверка типовl l2
не проверяет типk k1
не проверяет типk k2
проверка типовm m1
проверка типовm m2
не проверяет тип
Хотя я полностью согласен с тем, что происходит в l
и m
, я не понимаю часть k
. Существует своего рода отношение «более полиморфного», например, forall a. a -> a
более полиморфно, чем forall b. [b] -> [b]
, потому что можно просто заменить a/[b]
. Но почему это отношение переворачивается, если полиморфные типы находятся в контравариантных позициях?
Как я вижу, k
ожидает "машину, которая берет машину, работающую с любыми списками, которые производят Int". k1
- это «машина, которая принимает любую машину эндоморфизма, производящую int». Таким образом, k1
предлагает гораздо больше, чем хочет k
, так почему же это не соответствует его требованиям? Я чувствую, что в моих рассуждениях есть какая-то ошибка, но я не могу понять...