Действительно ли Rank2Types/RankNTypes практичны без переменных политипа?

Так как переменные типа не могут содержать политипы, кажется, что с Rank*Types мы не можем снова использовать существующие функции из-за их ограничения монотипа.

Например, мы не можем использовать функцию (.), когда промежуточный тип является политипом. Мы вынуждены повторно реализовать (.) в пятне. Это, конечно, тривиально для(.), но проблема для более существенных тел кода.

Я также думаю, делая ((f. g) x), не эквивалентный (f (g x)) серьезный удар по ссылочной прозрачности и ее преимуществам.

Это, кажется, мне проблема выставочного стопора и, кажется, делает расширения Rank*Types почти непрактичными для широкого использования.

Я пропускаю что-то? Существует ли план заставить Rank*Types взаимодействовать лучше с остальной частью системы типов?

Править: Как можно сделать типы (карлики. навсегда), удаются?

16
задан Don Stewart 19 April 2011 в 03:13
поделиться

3 ответа

Самым последним предложением для типов Rank-N является связанный документ FPH Дона. На мой взгляд, это также самое красивое из всех. Основная цель всех этих систем - требовать как можно меньше аннотаций типов. Проблема в том, что при переходе от Хиндли / Милнера к Системе F мы теряем основные типы, и вывод типа становится неразрешимым - отсюда и необходимость в аннотациях типов.

Основная идея работы с «квадратными типами» - максимально возможное распространение аннотаций типов. Средство проверки типов переключается между проверкой типов и режимом вывода типов, и, надеюсь, больше никаких аннотаций не требуется. Обратной стороной здесь является то, что трудно объяснить, требуется ли аннотация типа, потому что это зависит от деталей реализации.

Система MLF Реми - пока что самое хорошее предложение; он требует наименьшего количества аннотаций типов и стабилен при многих преобразованиях кода. Проблема в том, что он расширяет систему типов.Следующий стандартный пример иллюстрирует это:

choose :: forall a. a -> a -> a
id :: forall b. b -> b

choose id :: forall c. (c -> c) -> (c -> c)
choose id :: (forall c. c -> c) -> (forall c. c -> c)

Оба вышеупомянутых типа допустимы в Системе F. Первый - это стандартный тип Хиндли / Милнера и использует предикативное создание экземпляров, второй - импредикативное создание экземпляров. Ни один из типов не является более общим, чем другой, поэтому при выводе типов необходимо угадывать, какой тип нужен пользователю, а это обычно плохая идея.

MLF вместо этого расширяет систему F с помощью ограниченной количественной оценки. Основным (= наиболее общим) типом для приведенного выше примера будет:

choose id :: forall (a < forall b. b -> b). a -> a

Вы можете прочитать это как « select id имеет тип от a до a , где a должен быть экземпляром для всех b. B -> b ".

Интересно, что одно это не мощнее стандартного Хиндли / Милнера. Таким образом, MLF также позволяет жесткую количественную оценку. Следующие два типа эквивалентны:

(forall b. b -> b) -> (forall b. b -> b)
forall (a = forall b. b -> b). a -> a

Жесткая количественная оценка вводится с помощью аннотаций типов, и технические детали действительно довольно сложны. Плюс в том, что MLF нужно очень мало аннотаций типов, и есть простое правило, когда они нужны. Недостатки:

  • Типы могут стать труднее читать, потому что правая часть '<' может содержать дополнительные вложенные количественные характеристики.

  • До недавнего времени не существовало явно типизированного варианта MLF. Это важно для преобразований типизированного компилятора (как это делает GHC). В части 3 кандидатской диссертации Бориса Якобовского есть первая попытка такого варианта. (Части 1 и 2 также интересны; они описывают более интуитивное представление MLF через «Графические типы».)

Возвращаясь к FPH, его основная идея состоит в том, чтобы использовать методы MLF внутри, но требовать аннотации типов в привязках let . Если вам нужен только тип Хиндли / Милнера, то аннотации не требуются. Если вам нужен тип более высокого ранга, вам нужно указать запрошенный тип, но только в привязке let (или верхнего уровня).

FPH (как и MLF) поддерживает непредикативное создание экземпляров, поэтому я не думаю, что ваша проблема применима. Поэтому у него не должно возникнуть проблем с вводом вашего f. g выражение выше. Однако FPH еще не реализован в GHC и, скорее всего, не будет. Сложности возникают из-за взаимодействия с принуждением к равенству (и, возможно, с ограничениями классов типов). Я не уверен, каков последний статус, но я слышал, что SPJ хочет уйти от непредсказуемости. За всю эту выразительную силу приходится платить, и до сих пор не найдено доступного и комплексного решения.

11
ответ дан 30 November 2019 в 21:45
поделиться

Насчет ImpredicativeTypes: это не имеет никакого значения (я относительно уверен) для вопроса Пикера. Это расширение имеет отношение к типам данных. Например, GHC скажет вам, что:

Maybe :: * -> *
(forall a. a -> a) :: *

Однако, это своего рода ложь. Это верно в импредикативной системе, и в такой системе вы можете написать:

Maybe (forall a. a -> a) :: *

и это будет работать нормально. Это то, что позволяет ImpredicativeTypes. Без расширения подходящим способом думать об этом будет:

Maybe :: *m -> *m
(forall a :: *m. a -> a) :: *p

и поэтому при попытке сформировать вышеприведенное приложение возникает несоответствие вида.

Однако GHC довольно непоследователен в вопросах импредикативности. Например, тип для id, который я привел выше, будет:

id :: (forall a :: *m. a -> a)

но GHC с радостью примет аннотацию (с включенными RankNTypes, но не ImpredicativeTypes):

id :: (forall a. a -> a) -> (forall a. a -> a)

несмотря на то, что forall a. a -> a не является монотипом. Итак, он позволит импредикативное инстанцирование квантифицированных переменных, которые используются только с (->), если вы аннотируете их как таковые. Но он не будет делать этого сам, я полагаю, что это приводит к runST $ ... проблемам. Раньше это решалось с помощью специального правила инстанцирования (детали которого я так и не понял), но это правило было удалено вскоре после его добавления.

6
ответ дан 30 November 2019 в 21:45
поделиться

Есть ли план улучшить взаимодействие типов Rank * с остальной системой типов?

Учитывая, насколько распространена монада ST, по крайней мере, типы Rank2 достаточно распространены, чтобы свидетельствовать об обратном. Тем не менее, вы можете посмотреть серию статей «Сексуальные / квадратные типы», чтобы узнать, как подходы к созданию полиморфизма произвольного ранга лучше работают с другими.

FPH: Полиморфизм первого класса для Haskell , Димитриос Витиниотис, Стефани Вейрих и Саймон Пейтон Джонс, представлены на ICFP 2008.

См. Также -XImpredicativeTypes - что интересно, Планируется прекращение поддержки!

7
ответ дан 30 November 2019 в 21:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: