|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[11] >val plus = fn : int*int -> int -3 : bool Type clach in: 3 : bool Looking for a: bool I have found a: int -(plus, true) : (int*int -> int) * bool >(fn, true): (int*int -> int) * bool -fun id ( x : a ) = x; >val id = fn : a->a Заметьте, что в программе переменные типа записываются точно так же, как их выводит ML: апостроф, за которым следует идентификатор. Равенство является интересным промежуточным случаем. Равенство не является полиморфной функцией в том смысле, в каком таковой является функция append; однако, в противоположность сложению, равенство определено почти для всех типов. Как упоминалось выше, не все типы допускают проверку на равенство, однако для всех типов, допускающих проверку на равенство, существует функция =, которая возвращает true или false в соответствии с тем, равны или нет сравниваемые значения. Поскольку ML может сам определить, допускает тип проверку на равенство или нет, он позволяет использовать равенство "квазиполиморфным" путем. Для этого вводится новый сорт переменных типа, записываемых как "а, которые пробегают множество всех типов, допускающих проверку на равенство. Далее ML следит за тем, требуется или нет, чтобы какой-либо тип допускал проверку на равенство, и отражает этот фактНапример: -fun member (х, nil) = false I member (x, hd::tl) = if x=h then true else member(x,tl); >val member = fn : a * a list -> bool Вхождения "а в тип функции member указывают, что member может применяться только к аргументам, допускающим проверку на равенство. 2.7 Определения новых типов ML обладает расширяемой системой типов. Имеется три формы объявления идентификатора как нового конструктора типа. Простейшей формой является прозрачная привязка к типу, или введение сокращенного наименования типа. Конструктор типа (возможно, с параметрами) определяется как сокращение для некоторого (сложного) типового выражения. Все использования такого конструктора типа полностью эквивалентны использованию вместо него исходного выражения. -type intpair = int*int; >type intpair = int*int -fun f (x : intpair) = let val (l,r)=x in 1 end; >val f = fn : intpair -> int -f(3,2); >3 : int -type a pair = a*a; >type a pair = a*a -type boolpair = bool pair; >type boolpair = bool pair Нет никакой разницы между intpair и int*int, поскольку тип intpair определен равным типу int*int. Единственная причина, по которой ML печатает intpair в типе функции f - это то, что этот тип явно был указан при объявлении функции. Система типов ML может быть также расширена с помощью рекурсивно определяемых типов (или, короче, рекурсивных типов)11. В этой конструкции указывается имя нового типа (возможно, с параметрами) и набор конструкторов значений для построения объектов этого типа. В простейшем случае рекурсивное объявление типа выглядит так: -datatype color = Red I Blue I Yellow; >type color con Red : color con Blue : color con Yellow : color >Red : color Приведенное объявление привязывает идентификатор color к новому типу данных, имеющему конструкторы Red, Blue и Yellow12. Этот случай рекурсивного объявления напоминает перечислимые типы в Pascale. Обратите внимание на то, что ML выводит слово color без последующего знака равенства, подчеркивая этим, что color является новым типом данных: он не совпадает ни с каким ранее определенным типом данных, и поэтому равенство здесь было бы неуместным. Кроме объявления нового типа, приведенная выше конструкция datatype объявляет 11Этот способ определения новых типов предоставляет многообразные возможности и является, пожалуй, наиболее важным в системе типов ML (да и других функциональных языков). Название рекурсивный отражает лишь одну (хотя и наиболее существенную) черту этого способа определения типов. Это название не является повсеместно принятым: так, например, в Haskelle используется термин алгебраический: чаще же всего в англоязычной литературе используется термин datatype (просто копирующий вводящее определение ключевое слово) - однако дословный перевод этого термина (тип данных) в русском языке не отражает особенностей этого понятия. (Прим. перев.) 12Конструкторы без аргументов иногда называют константами. также три новых конструктора значений. Эти конструкторы выводятся с предшествующим ключевым словом con (а не val), подчеркивая тем самым, что это конструкторы. Введенные конструкторы могут быть использованы для построения образцов при определении функции разбором случаев. Таким образом, рекурсивное определение типа является достаточно сложным: оно одновременно вводит и новый конструктор типа, и новые конструкторы значений. Рекурсивные определения типов широко используются в ML. Например, можно считать, что встроенный тип bool объявлен как: -datatype bool = true I false; >type bool con true : bool con false: bool Функции, аргументы которых имеют типы, введенные пользователем, могут быть определены путем разбора случаев так же, как и в случае исходных типов языка. При этом конструкторы значений могут быть использованы в образцах точно так же, как ранее мы использовали nil и : : при определении функций, работающих со списками. Например: -fun favorite Red = true I favorite Blue = false I favorite Yellow = false; >val favorite = fn : color->bool -val color = Red; >val color = Red : color -favorite color; >true : bool Этот пример также иллюстрирует возможность использования одного и того же идентификатора для нескольких различных целей. Идентификатор color используется и как имя определенного выше типа, и как переменная, привязанная к Red. Такое двойное использование не запрещено (хотя и не рекомендуется, поскольку может привести к затемнению смысла программы), поскольку компилятор всегда может понять из контекста, должно ли в данном месте находится имя типа или имя переменной. Определяемые пользователем конструкторы значений могут иметь аргументы: -datatype money = nomoney I coin of int I note of int I check of string*int; >type money con nomoney : money con coin : int->money |
Среды: Smalltalk80 MicroCap Local bus Bios Pci 12С ML Микроконтроллеры: Atmel Intel Holtek AVR MSP430 Microchip Книги: Емкостный датчик 500 схем для радиолюбителей часть 2 (4) Структура компьютерных программ Автоматическая коммутация Кондиционирование и вентиляция Ошибки при монтаже Схемы звуковоспроизведения Дроссели для питания Блоки питания Детекторы перемещения Теория электропривода Адаптивное управление Измерение параметров Печатная плата pcad pcb Физика цвета Управлении софтверными проектами Математический аппарат Битовые строки Микроконтроллер nios Команды управления выполнением программы Перехода от ahdl к vhdl Холодный спай Усилители hi-fi Электронные часы Сердечники из распылённого железа Анализ алгоритмов 8-разрядные КМОП Классификация МПК История Устройства автоматики Системы и сети Частотность Справочник микросхем Вторичного электропитания Типы видеомониторов Радиобиблиотека Электронные системы Бесконтекстный язык Управление техническими системами Монтаж печатных плат Работа с коммуникациями Создание библиотечного компонента Нейрокомпьютерная техника Parser Пи-регулятор ч.1 ПИ-регулятор ч.2 Обработка списков Интегральные схемы Шина ISAВ Шина PCI Прикладная криптография Нетематическое: Взрывной автогидролиз Нечеткая логика Бытовые установки (укр) Автоматизация проектирования Сбор и защита Дискретная математика Kb радиостанция Энергетика Ретро: Прием в автомобиле Управление шаговым двигателем Магнитная запись Ремонт микроволновки Дискретные системы часть 2 | ||