|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[6] Иногда удобно выполнить частичное сопоставление записи с образцом. Это может быть выполнено с помощью универсального образца для записей, как в следующем примере: -val {used=u,...} = г; >val u = true : bool Существенным ограничением при использовании универсального образца для записей является следующее: полный тип записи должен определяться на этапе компиляции (т.е. полный список имен полей записи и их типов должен определяться по контексту, в который входит образец). Поскольку выделение одного поля из записи является широко распространенной операцией, для нее предусмотрено специальное обозначение: поле name записи г может быть обозначено как #name г. На самом деле #name является не более чем сокращенным обозначением для функции fix {name=n, . . .} => п, выделяющей поле name из записи. Поэтому, в частности, тип записи должен определяться из контекста, в котором эта функция используется. Например, fix х => #ixame х будет ошибкой, поскольку тип записи х не определяется однозначно контекстом. Поскольку упорядоченные энки являются частным случаем записи (именами полей у них являются целые числа от 1 до и), г-тая компонента упорядоченной энки может быть выделена с помощью функции #i. Образцы могут вкладываться друг в друга, как в приводимом ниже примере: -val х = (("fоо",true), 17); >val x = (("f oo" ,true), 17) : (string*bool)*int -val ((11,lr), r) = x; >val 11 = "foo" : string val lr = true : bool val r = 17 : int Иногда бывает удобно ввести "промежуточные" переменные в образце. Например, нам может понадобиться привязать к паре (11, гг) идентификатор 1. Это выполняется с помощью многоуровневых образцов. Многоуровневый образец получается путем приписывания образца к переменной внутри другого образца, как в следующем примере: -val х = (("foo", true), 17); >val x = (("foo", true), 17): (string*bool)*int -val (1 as (11,lr), r) = x; >val 1 = ("foo", true): string*bool val 11 = "foo": string val lr = true : bool val r = 17 : int Здесь сопоставление с образцом выполняется обычным способом: 1 и г привязываются к значениям левой и правой компонент х, но дополнительно производится сопоставление привязанного к 1 значения с образцом (11,1г). Результат выводится как обычно. Имеется еще одно важное ограничение: любая переменная может входить в образец только один раз. В частности, нельзя задать образец вроде (х,х) - который должен был бы быть сопоставим только с симметричными парами. Это ограничение на практике не вызывает трудностей, но упомянуть его необходимо. Упражнение 2.4.2 Постройте образец, который привязывал бы переменную х к значению 0 при сопоставлении со следующим выражением (например, если дано выражение (true, "hello" ,0), образцом должно быть ( , ,х): 1.{а=1, b=0, c=true> 2.[~2, ~1, 0, 1, 2] 3.[(1,2), (0,1)] 2.5 Определения функций Мы уже использовали предопределенные функции, такие, как арифметические операции и операции сравнения. В этом разделе мы рассмотрим привязки к функциональным значениям, посредством которых в ML определяются новые функции. Начнем с нескольких общих замечаний, касающихся понятия функции в ML. Функции используются путем применения их к аргументам (мы будем также использовать термин аппликация). Синтаксически это записывается как два выражения одно за другим (значением первого выражения должна являться функция, а значением второго - ее аргумент) - как, например, size "abc" для вызова функции size с аргументом "abc". Все функции являются функциями одного аргумента; при необходимости использовать функции (содержательно) нескольких аргументов, n аргументов функции "упаковываются" в один - упорядоченную энку. Так, например, если функция append должна получать два аргумента-списка и возвращать результат-список, применение ее будет иметь вид append(ll ,12): формально функция применяется к одному аргументу, который является упорядоченной парой (11,12). Для некоторых функций от двух аргументов (обычно, встроенных) используется специальный синтаксис - так называемая инфиксная запись, в которой знак функции записывается между двумя ее аргументами. Например, запись в\ + в2 в действительности означает "применить функцию + к упорядоченной паре (ei, в2)". Можно использовать инфиксную запись и для функций, определяемых пользователем, однако мы не будем здесь на этом останавливаться. Аппликация в ML может иметь более сложную форму, чем в других языках программирования. Причиной этого является следующее: в большинстве языков программирования функция может обозначаться только идентификатором, и поэтому вызов функции всегда имеет вид f(ei, . . . ,en), где f - идентификатор. В ML нет такого ограничения: функция является обычным значением, и может быть получена в результате вычисления выражения. Поэтому в общем случае аппликация в ML имеет вид ее. Вычисление такого выражения выполняется следующим образом: сначала вычисляется выражение в, в результате чего получается некоторая функция /; затем вычисляется выражение в, в результате чего получается некоторое значение у; после этого функция / применяется к значению v. В простейшем случае, когда выражение в ся крайне простой операцией: нужно просто взять значение, к которому привязан идентификатор (оно должно быть функцией). Но в общем слу- те внимание на то, что правила вычисления аппликации предполагают передачу аргумента по значению, поскольку аргумент вычисляется до применения функции. число)? Чтобы ответить на этот вопрос, конечно, следует посмотреть, в в ML имеет тип. Функциональные типы являются составными типами, членами которых являются функции. Функциональные типы записываются как а -> т (произносится "а в т"), где а и т - типы. Выражение такого типа имеет в качестве значения функцию, которая может быть (к сожалению, в общем случае невозможно определить, завершается ли а тв ат Например: >size = fix : string -> int >not = fn : bool -> bool -not 3; Type clash in: not 3 |
Среды: 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 | ||