Переменная типа
Переменная типа (ти́повая переменная) в языках программирования и теории типов — переменная, которая может принимать значение из множества типов данных.
Ти́повая переменная используется в определении алгебраического типа данных подобно тому, как используется параметр в определении функции, но используется для передачи типа данных без передачи самих данных. В качестве идентификаторов ти́повых переменных в теории типов традиционно используются буквы греческого алфавита (хотя многие языки программирования используют латиницу и допускают и более длинные именования).
Пример
В следующем определении полиморфного типа «список» на языке Standard ML, идентификатор 'a (читается «альфа») является переменной типа:
datatype 'a list = nil | :: of 'a * 'a list При использовании этого полиморфного типа, в ти́повую переменную подставляется конкретный тип, так что в программе может быть сформировано множество мономорфных типов: string list, int list, int list list и так далее. При такой подстановке, вместо каждого упоминания переменной типа подставляется один и тот же тип. Полученная информация о типах используется для верификации и оптимизации программы, после чего обычно стирается, так что один и тот же целевой код обрабатывает объекты изначально разных типов (но существуют и исключения из этого правила, в частности, в MLton).
Если полиморфный тип параметризован несколькими переменными типа, то подставляемые в них типы могут быть как разными, так и идентичными, но правило подстановки соблюдается. Например, если такой тип:
datatype ('a,'b) t = Single of 'a | Double of 'a * 'a | Pair of 'a * 'b инстанцировать следующим образом:
type t_ir = (int, real) t то Single(4), Double(4,5) и Pair(4,5.0) будут допустимыми значениями типа t_ir, а попытка построить значение Single(5.0) приведёт к ошибке типизации, поскольку параметр 'a получил значение «int».
Связывание и квантификация
Область действия всякой ти́повой переменной привязывается к определённому контексту. В следующем примере идентификатор 'a используется в двух сигнатурах независимо, то есть не означает требование равенства фактически подставляемых типов между определениями:
val foo: 'a -> 'a val bar: 'a -> 'a Это становится наглядным при использовании явного связывания (explicit scoping или explicit bounding) ти́повой переменной:
val foo: ['a] 'a -> 'a val bar: ['a] 'a -> 'a Связывание ограничивает область действия данной переменной типа.
В классических диалектах ML явное связывание ти́повых переменных является необязательной возможностью и большинством реализаций не поддерживается за ненадобностью — связывание в них осуществляется неявно при выведении типов, что становится возможным за счёт ограничений ранних версий системы Хиндли — Милнера. В полной системе F это объявление записывается как . Такая запись называется [англ.]. Заглавная
в этой записи означает функцию слоя типов (type-level function), параметром которой и является переменная типа. После подстановки в эту переменную конкретного типа, эта функция возвращает мономорфную функцию слоя значений (value-level function). Пренексом называется вынесенное в качестве префикса к сигнатуре типа явное связывание переменной типа. Ранние версии системы Хиндли — Милнера разрешают только пренексную форму, то есть требуют, чтобы инстанцирование ти́повой переменной определённым значением было произведено до необходимости обращения к функции. Это ограничение называется пренексным полиморфизмом — оно не только существенно упрощает механизм проверки согласования типов, но и делает возможным выведение всех или почти всех (в зависимости от диалекта) типов в программе.
Простейшее связывание ти́повых переменных называется их квантификацией. Выделяются два случая:
- действие переменной типа распространяется на всё определение типа:
['a, 'b] 'a -> 'b -> 'a, математически такой тип записывается через квантор всеобщности —— поэтому такая переменная типа называется «универсально квантифицированной», а весь тип — «универсально полиморфным»;
- действие переменной типа распространяется только на часть определения типа:
['a] 'a -> (['b] 'b -> 'a), математически такой тип записывается через квантор существования —— поэтому такая переменная называется «экзистенциально квантифицированной», а весь тип — «экзистенциальным».
Далеко не во всех случаях «превращение» универсально полиморфного типа в экзистенциальный даёт применимый на практике тип или заметные отличия от универсального полиморфизма, но в определённых случаях использование экзистенциальных типов поднимает параметрический полиморфизм на первоклассный уровень, т.е. позволяет передавать полиморфные функции без связывания в качестве параметров другим функциям (см. полиморфизм первого класса). Классическим примером является реализация гетерогенного списка (см. викиучебник). Явное аннотирование типов в этом случае становится обязательным, т.к. выведение типов для полиморфизма выше ранга 2 алгоритмически неразрешимо.
На практике, универсально полиморфные типы дают обобщённость типа данных, а экзистенциальные — абстрактность типа данных.
В языке Haskell различают несколько режимов (доступных в виде расширений языка): режим Rank2Types разрешает лишь некоторые формы экзистенциальных типов, открывающие полиморфизм не выше 2-го ранга, для которого выведение типов ещё разрешимо; режим RankNTypes разрешает перемещать универсальный квантор (forall a) внутрь функциональных типов, входящих в состав более сложных сигнатур, режим ImpredicativeTypes разрешает произвольные экзистенциальные типы.
OCaml реализует поддержку экзистенциальной квантификации посредством решения, названного «локально-абстрактными типами» (locally abstract types).
В спецификации Standard ML для некоторых встроенных операций определена особая квантификация. Её синтаксис не регламентирован и различается в реализациях языка (чаще всего просто скрывается). Например, сигнатура встроенной операции сложения может упрощённо выглядеть примерно следующим образом:
val + : [int, word, real] 'a * 'a -> 'a Эта семантика реализует примитивную форму ad-hoc-полиморфизма — объединение нескольких физически различных операций сложения под единым идентификатором «+». Разработчики OCaml отказались от такого решения, полностью убрав ad-hoc-полиморфизм из языка (в более поздних версиях появились обобщённые алгебраические типы данных).
В конце 1980-х появилось расширение Хиндли — Милнера, предоставляющее возможность ограничивать по необходимости диапазон значений для всякой ти́повой переменной во вновь определяемых типах — классы типов. Класс типов строже ограничивает допустимые контексты типизации, разрешая инстанцирование ти́повой переменной лишь типами, принадлежащими явно указанному классу.
Впервые это расширение было реализовано в основе языка Haskell, например, операция сравнения на равенство имеет в нём следующую [англ.]:
(==) :: (Eq a) => a -> a -> Bool Проект языка следующего поколения — successor ML — отказывается от необходимости выведения типов, опираясь на явное (манифестное) аннотирование типов (в том числе явное связывание переменных типа), что обеспечивает непосредственную поддержку полной системы F с полиморфизмом первого класса и рядом расширений, в том числе [англ.] и экзистенциальных типов.
Специальные переменные типа
Основным классом переменных типа, используемым во всех языках семейства ML, являются аппликативные переменные типа, могут принимать значения из множества всех допустимых в конкретном языке типов. В классических диалектах они синтаксически обозначаются как «'a» (цифробуквенный идентификатор, всегда начинающийся с одного апострофа); в Haskell как «a» (цифробуквенный идентификатор, всегда начинающийся со строчной буквы).
Кроме этого, на протяжении истории развития ML выделялись специальные подклассы переменных типа.
Переменные типа, допускающего проверку на равенство (или переменные сравниваемого типа, equality type variables) — могут принимать значения из множества всех (англ. equality types). Их использование разрешает применение операции сравнения на равенство к объектам полиморфных типов. Обозначаются как «''a» (цифробуквенный идентификатор, всегда начинающийся с двух апострофов). Интересно, что одной из первоначальных целей, ради которых были разработаны классы типов, было именно обобщение таких ти́повых переменных из Standard ML. Они неоднократно подвергалась критике из-за существенного (и спорно оправданного) усложнения определения языка и реализации компиляторов (половина страниц Определения содержат ту или иную поправку на них). Сложные абстрактные типы данных в принципе не целесообразно проверять на равенство, так как такие проверки могут требовать существенных затрат времени. Поэтому из более поздних языков семейства ML поддержка переменных типа, допускающего проверку на равенство, была исключена. В Haskell вместо них используется класс типов Eq a.
Императивные переменные типа (imperative type variables) обеспечивали ситуативное решение проблемы типобезопасности, связанной с наличием побочных эффектов в языке с параметрическим полиморфизмом. Этой проблемы не возникает в чистых языках (Haskell, Clean), но для нечистых языков (Standard ML, OCaml) полиморфизм ссылок представляет угрозу ошибок типизации. Императивные переменные типа входили в Определение SML’90, но перестали иметь собственный смысл после того как было придумано «ограничение значениями» (value restriction), ставшее частью пересмотренного определения SML’97. Синтаксическая поддержка императивных переменных типа в SML’97 была сохранена для обратной совместимости с написанным ранее кодом, но современные реализации трактуют их идентично аппликативным. Обозначаются «'_a» (цифробуквенный идентификатор, всегда начинающийся с апострофа и символа подчёркивания).
Слабые переменные типа (weak type variables) использовались в компиляторе [англ.] в качестве альтернативы императивным переменным типа, предоставляя существенно большие возможности (точнее, меньшие ограничения). Обозначаются «'1a», «'2a» и так далее (цифробуквенный идентификатор, всегда начинающийся с апострофа и цифры). Цифра, непосредственно идущая за апострофом, показывала градацию «слабости» переменной типа. Как и императивные переменные типа, ныне трактуются идентично аппликативным.
Примечания
- ML2000, 1999.
- Здесь для явного связывания (explicit binding) ти́повой переменной используется текущий синтаксис, принятый в проекте successor ML:
['a]. Из-за того, что в Haskell этот синтаксис был назначен в качестве синтаксического сахара над типомList, для объявления ти́повых переменных в нём было введено ключевое словоforall. - MacQueen - TypeChecking.
- MLton - Scoping.
- haskell_existentials.
- Cardelli, Wegner, 1985.
- haskell_rankNtypes.
- haskell_impredicative_types.
- OCaml extenstions. 7.13 Locally abstract types
- Philip Wadler, Stephen Blott. How to make ad-hoc polymorphism less ad hoc. — 1988. Архивировано 11 марта 2016 года.
- Andrew W. Appel. A Critique of Standard ML. — Princeton University, revised version of CS-TR-364-92, 1992. Архивировано 5 марта 2016 года.
Литература
- Luca Cardelli, Peter Wegner. On Understanding Types, Data Abstraction, and Polymorphism. — , 1985. — С. 471—523. — ISSN 0360-0300.
- Dave MacQueen. SML'97 Conversion Guide. 1.1. Types and Type Checking.
Ссылки
- Haskell-Wiki: Existential types.
- Haskell-Wiki: Rank-N types.
- Haskell-Wiki: Impredicative types.
- Scoping type variables in Standard ML.
- The ML2000 Working Group. Principles and a Preliminary Design for ML2000. — 1999.
Википедия, чтение, книга, библиотека, поиск, нажмите, истории, книги, статьи, wikipedia, учить, информация, история, скачать, скачать бесплатно, mp3, видео, mp4, 3gp, jpg, jpeg, gif, png, картинка, музыка, песня, фильм, игра, игры, мобильный, телефон, Android, iOS, apple, мобильный телефон, Samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Сеть, компьютер, Информация о Переменная типа, Что такое Переменная типа? Что означает Переменная типа?
Peremennaya tipa ti povaya peremennaya v yazykah programmirovaniya i teorii tipov peremennaya kotoraya mozhet prinimat znachenie iz mnozhestva tipov dannyh Ti povaya peremennaya ispolzuetsya v opredelenii algebraicheskogo tipa dannyh podobno tomu kak ispolzuetsya parametr v opredelenii funkcii no ispolzuetsya dlya peredachi tipa dannyh bez peredachi samih dannyh V kachestve identifikatorov ti povyh peremennyh v teorii tipov tradicionno ispolzuyutsya bukvy grecheskogo alfavita hotya mnogie yazyki programmirovaniya ispolzuyut latinicu i dopuskayut i bolee dlinnye imenovaniya PrimerV sleduyushem opredelenii polimorfnogo tipa spisok na yazyke Standard ML identifikator a chitaetsya alfa yavlyaetsya peremennoj tipa datatype a list nil of a a list Pri ispolzovanii etogo polimorfnogo tipa v ti povuyu peremennuyu podstavlyaetsya konkretnyj tip tak chto v programme mozhet byt sformirovano mnozhestvo monomorfnyh tipov string list int list int list list i tak dalee Pri takoj podstanovke vmesto kazhdogo upominaniya peremennoj tipa podstavlyaetsya odin i tot zhe tip Poluchennaya informaciya o tipah ispolzuetsya dlya verifikacii i optimizacii programmy posle chego obychno stiraetsya tak chto odin i tot zhe celevoj kod obrabatyvaet obekty iznachalno raznyh tipov no sushestvuyut i isklyucheniya iz etogo pravila v chastnosti v MLton Esli polimorfnyj tip parametrizovan neskolkimi peremennymi tipa to podstavlyaemye v nih tipy mogut byt kak raznymi tak i identichnymi no pravilo podstanovki soblyudaetsya Naprimer esli takoj tip datatype a b t Single of a Double of a a Pair of a b instancirovat sleduyushim obrazom type t ir int real t to Single 4 Double 4 5 i Pair 4 5 0 budut dopustimymi znacheniyami tipa t ir a popytka postroit znachenie Single 5 0 privedyot k oshibke tipizacii poskolku parametr a poluchil znachenie int Svyazyvanie i kvantifikaciyaOblast dejstviya vsyakoj ti povoj peremennoj privyazyvaetsya k opredelyonnomu kontekstu V sleduyushem primere identifikator a ispolzuetsya v dvuh signaturah nezavisimo to est ne oznachaet trebovanie ravenstva fakticheski podstavlyaemyh tipov mezhdu opredeleniyami val foo a gt a val bar a gt a Eto stanovitsya naglyadnym pri ispolzovanii yavnogo svyazyvaniya explicit scoping ili explicit bounding ti povoj peremennoj val foo a a gt a val bar a a gt a Svyazyvanie ogranichivaet oblast dejstviya dannoj peremennoj tipa V klassicheskih dialektah ML yavnoe svyazyvanie ti povyh peremennyh yavlyaetsya neobyazatelnoj vozmozhnostyu i bolshinstvom realizacij ne podderzhivaetsya za nenadobnostyu svyazyvanie v nih osushestvlyaetsya neyavno pri vyvedenii tipov chto stanovitsya vozmozhnym za schyot ogranichenij rannih versij sistemy Hindli Milnera V polnoj sisteme F eto obyavlenie zapisyvaetsya kak La lxa x displaystyle Lambda alpha lambda x alpha x Takaya zapis nazyvaetsya angl Zaglavnaya L displaystyle Lambda v etoj zapisi oznachaet funkciyu sloya tipov type level function parametrom kotoroj i yavlyaetsya peremennaya tipa Posle podstanovki v etu peremennuyu konkretnogo tipa eta funkciya vozvrashaet monomorfnuyu funkciyu sloya znachenij value level function Preneksom nazyvaetsya vynesennoe v kachestve prefiksa k signature tipa yavnoe svyazyvanie peremennoj tipa Rannie versii sistemy Hindli Milnera razreshayut tolko preneksnuyu formu to est trebuyut chtoby instancirovanie ti povoj peremennoj opredelyonnym znacheniem bylo proizvedeno do neobhodimosti obrasheniya k funkcii Eto ogranichenie nazyvaetsya preneksnym polimorfizmom ono ne tolko sushestvenno uproshaet mehanizm proverki soglasovaniya tipov no i delaet vozmozhnym vyvedenie vseh ili pochti vseh v zavisimosti ot dialekta tipov v programme Prostejshee svyazyvanie ti povyh peremennyh nazyvaetsya ih kvantifikaciej Vydelyayutsya dva sluchaya dejstvie peremennoj tipa rasprostranyaetsya na vsyo opredelenie tipa a b a gt b gt a matematicheski takoj tip zapisyvaetsya cherez kvantor vseobshnosti a b a b a displaystyle forall a forall b a rightarrow b rightarrow a poetomu takaya peremennaya tipa nazyvaetsya universalno kvantificirovannoj a ves tip universalno polimorfnym dejstvie peremennoj tipa rasprostranyaetsya tolko na chast opredeleniya tipa a a gt b b gt a matematicheski takoj tip zapisyvaetsya cherez kvantor sushestvovaniya a b a b a displaystyle forall a exists b a rightarrow b rightarrow a poetomu takaya peremennaya nazyvaetsya ekzistencialno kvantificirovannoj a ves tip ekzistencialnym Daleko ne vo vseh sluchayah prevrashenie universalno polimorfnogo tipa v ekzistencialnyj dayot primenimyj na praktike tip ili zametnye otlichiya ot universalnogo polimorfizma no v opredelyonnyh sluchayah ispolzovanie ekzistencialnyh tipov podnimaet parametricheskij polimorfizm na pervoklassnyj uroven t e pozvolyaet peredavat polimorfnye funkcii bez svyazyvaniya v kachestve parametrov drugim funkciyam sm polimorfizm pervogo klassa Klassicheskim primerom yavlyaetsya realizaciya geterogennogo spiska sm vikiuchebnik Yavnoe annotirovanie tipov v etom sluchae stanovitsya obyazatelnym t k vyvedenie tipov dlya polimorfizma vyshe ranga 2 algoritmicheski nerazreshimo Na praktike universalno polimorfnye tipy dayut obobshyonnost tipa dannyh a ekzistencialnye abstraktnost tipa dannyh V yazyke Haskell razlichayut neskolko rezhimov dostupnyh v vide rasshirenij yazyka rezhim Rank2Types razreshaet lish nekotorye formy ekzistencialnyh tipov otkryvayushie polimorfizm ne vyshe 2 go ranga dlya kotorogo vyvedenie tipov eshyo razreshimo rezhim RankNTypes razreshaet peremeshat universalnyj kvantor forall a vnutr funkcionalnyh tipov vhodyashih v sostav bolee slozhnyh signatur rezhim ImpredicativeTypes razreshaet proizvolnye ekzistencialnye tipy OCaml realizuet podderzhku ekzistencialnoj kvantifikacii posredstvom resheniya nazvannogo lokalno abstraktnymi tipami locally abstract types V specifikacii Standard ML dlya nekotoryh vstroennyh operacij opredelena osobaya kvantifikaciya Eyo sintaksis ne reglamentirovan i razlichaetsya v realizaciyah yazyka chashe vsego prosto skryvaetsya Naprimer signatura vstroennoj operacii slozheniya mozhet uproshyonno vyglyadet primerno sleduyushim obrazom val int word real a a gt a Eta semantika realizuet primitivnuyu formu ad hoc polimorfizma obedinenie neskolkih fizicheski razlichnyh operacij slozheniya pod edinym identifikatorom Razrabotchiki OCaml otkazalis ot takogo resheniya polnostyu ubrav ad hoc polimorfizm iz yazyka v bolee pozdnih versiyah poyavilis obobshyonnye algebraicheskie tipy dannyh V konce 1980 h poyavilos rasshirenie Hindli Milnera predostavlyayushee vozmozhnost ogranichivat po neobhodimosti diapazon znachenij dlya vsyakoj ti povoj peremennoj vo vnov opredelyaemyh tipah klassy tipov Klass tipov strozhe ogranichivaet dopustimye konteksty tipizacii razreshaya instancirovanie ti povoj peremennoj lish tipami prinadlezhashimi yavno ukazannomu klassu Vpervye eto rasshirenie bylo realizovano v osnove yazyka Haskell naprimer operaciya sravneniya na ravenstvo imeet v nyom sleduyushuyu angl Eq a gt a gt a gt Bool Proekt yazyka sleduyushego pokoleniya successor ML otkazyvaetsya ot neobhodimosti vyvedeniya tipov opirayas na yavnoe manifestnoe annotirovanie tipov v tom chisle yavnoe svyazyvanie peremennyh tipa chto obespechivaet neposredstvennuyu podderzhku polnoj sistemy F s polimorfizmom pervogo klassa i ryadom rasshirenij v tom chisle angl i ekzistencialnyh tipov Specialnye peremennye tipaOsnovnym klassom peremennyh tipa ispolzuemym vo vseh yazykah semejstva ML yavlyayutsya applikativnye peremennye tipa mogut prinimat znacheniya iz mnozhestva vseh dopustimyh v konkretnom yazyke tipov V klassicheskih dialektah oni sintaksicheski oboznachayutsya kak a cifrobukvennyj identifikator vsegda nachinayushijsya s odnogo apostrofa v Haskell kak a cifrobukvennyj identifikator vsegda nachinayushijsya so strochnoj bukvy Krome etogo na protyazhenii istorii razvitiya ML vydelyalis specialnye podklassy peremennyh tipa Peremennye tipa dopuskayushego proverku na ravenstvo ili peremennye sravnivaemogo tipa equality type variables mogut prinimat znacheniya iz mnozhestva vseh angl equality types Ih ispolzovanie razreshaet primenenie operacii sravneniya na ravenstvo k obektam polimorfnyh tipov Oboznachayutsya kak a cifrobukvennyj identifikator vsegda nachinayushijsya s dvuh apostrofov Interesno chto odnoj iz pervonachalnyh celej radi kotoryh byli razrabotany klassy tipov bylo imenno obobshenie takih ti povyh peremennyh iz Standard ML Oni neodnokratno podvergalas kritike iz za sushestvennogo i sporno opravdannogo uslozhneniya opredeleniya yazyka i realizacii kompilyatorov polovina stranic Opredeleniya soderzhat tu ili inuyu popravku na nih Slozhnye abstraktnye tipy dannyh v principe ne celesoobrazno proveryat na ravenstvo tak kak takie proverki mogut trebovat sushestvennyh zatrat vremeni Poetomu iz bolee pozdnih yazykov semejstva ML podderzhka peremennyh tipa dopuskayushego proverku na ravenstvo byla isklyuchena V Haskell vmesto nih ispolzuetsya klass tipov Eq a Imperativnye peremennye tipa imperative type variables obespechivali situativnoe reshenie problemy tipobezopasnosti svyazannoj s nalichiem pobochnyh effektov v yazyke s parametricheskim polimorfizmom Etoj problemy ne voznikaet v chistyh yazykah Haskell Clean no dlya nechistyh yazykov Standard ML OCaml polimorfizm ssylok predstavlyaet ugrozu oshibok tipizacii Imperativnye peremennye tipa vhodili v Opredelenie SML 90 no perestali imet sobstvennyj smysl posle togo kak bylo pridumano ogranichenie znacheniyami value restriction stavshee chastyu peresmotrennogo opredeleniya SML 97 Sintaksicheskaya podderzhka imperativnyh peremennyh tipa v SML 97 byla sohranena dlya obratnoj sovmestimosti s napisannym ranee kodom no sovremennye realizacii traktuyut ih identichno applikativnym Oboznachayutsya a cifrobukvennyj identifikator vsegda nachinayushijsya s apostrofa i simvola podchyorkivaniya Slabye peremennye tipa weak type variables ispolzovalis v kompilyatore angl v kachestve alternativy imperativnym peremennym tipa predostavlyaya sushestvenno bolshie vozmozhnosti tochnee menshie ogranicheniya Oboznachayutsya 1a 2a i tak dalee cifrobukvennyj identifikator vsegda nachinayushijsya s apostrofa i cifry Cifra neposredstvenno idushaya za apostrofom pokazyvala gradaciyu slabosti peremennoj tipa Kak i imperativnye peremennye tipa nyne traktuyutsya identichno applikativnym PrimechaniyaML2000 1999 Zdes dlya yavnogo svyazyvaniya explicit binding ti povoj peremennoj ispolzuetsya tekushij sintaksis prinyatyj v proekte successor ML a Iz za togo chto v Haskell etot sintaksis byl naznachen v kachestve sintaksicheskogo sahara nad tipom a href wiki D0 A1 D0 BF D0 B8 D1 81 D0 BE D0 BA D0 BF D1 80 D0 BE D0 B3 D1 80 D0 B0 D0 BC D0 BC D0 B8 D1 80 D0 BE D0 B2 D0 B0 D0 BD D0 B8 D0 B5 class mw redirect title Spisok programmirovanie List a dlya obyavleniya ti povyh peremennyh v nyom bylo vvedeno klyuchevoe slovo forall MacQueen TypeChecking MLton Scoping haskell existentials Cardelli Wegner 1985 haskell rankNtypes haskell impredicative types OCaml extenstions 7 13 Locally abstract types Philip Wadler Stephen Blott How to make ad hoc polymorphism less ad hoc 1988 Arhivirovano 11 marta 2016 goda Andrew W Appel A Critique of Standard ML Princeton University revised version of CS TR 364 92 1992 Arhivirovano 5 marta 2016 goda LiteraturaLuca Cardelli Peter Wegner On Understanding Types Data Abstraction and Polymorphism 1985 S 471 523 ISSN 0360 0300 Dave MacQueen SML 97 Conversion Guide 1 1 Types and Type Checking SsylkiHaskell Wiki Existential types neopr Haskell Wiki Rank N types neopr Haskell Wiki Impredicative types neopr Scoping type variables in Standard ML neopr The ML2000 Working Group Principles and a Preliminary Design for ML2000 1999
