|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[9] Выше было подчеркнуто, что функции в ML являются полноправными значениями; они имеют те же права и те же привилегии, что и любые другие значения. В частности, это означает, что функции могут быть переданы в качестве аргумента другим функциям и могут быть выработаны функциями в качестве результата. Функции, какие-либо аргументы или результат которых являются функциями, иногда называют функциями высших порядков. Эта терминология подчеркивает, что функции являются существенно более сложными объектами - в отличие, например, от целых чисел (которые называют "объектами первого порядка"). Однако, обращаем ваше внимание на то, что в ML нет никакой принципиальной разницы между, например, функциями, получающими в качестве аргумента число, и функциями, получающими в качестве аргумента другую функцию; поэтому упомянутая терминология может указывать разве что на содержательный способ использования функции. Рассмотримфункции, которые вырабатывают функции в ка- честве результата. Пусть f - такая функция. Что тогда можно сказать о ее типе? Пусть она имеет один аргумент типа т и вырабатывает результат типа а->р. Тогда тип функции f есть т->(а->р). Результат применения функции f к аргументу типа т есть функция типа о~->р, которая может быть применена к аргументу типа о и выработать результат типа р. Такое последовательное применение записывается как f(e\) (в2), или просто ie\&2- Заметьте, что это не то же самое, что f(e\,e2)\ (ei,e2) есть один объект - упорядоченная пара, и f(e\, e2) означает "применить функцию f к упорядоченной паре (e\,в2)", в то время как ie\t2 означает "применить f к ei, получить функцию и приме нить ее к в2". Теперь становится понятным, почему ранее при объяснении понятия применения функции к аргументу мы подчеркивали, что функция вычисляется: здесь мы получили пример того, что функция задана не идентификатором, а сложным выражением. Приведем несколько примеров, проясняющих сказанное: -fun times (x:int) (у:int) = х*у; >val times = fn : int->(int->int) -val twice = times 2; >val twice = fn: int->int -twice 4; >8 : int -times 3 4; >12: int Функция times определена как функция, берущая в качестве аргумента целое число и вырабатывающая функцию, берущую в качестве аргумента целое число и вырабатывающую целое число9. Идентификатор twice Необходимость ": int" при х и у будет объяснена далее в разделе 2.6. привязывается к значению times 2. Поскольку 2 имеет тип int, функция times может быть применена к 2, и результатом будет объект типа int->int - как это и видно из сообщения о типе twice. Так как twice есть функция, она может быть применена к аргументу - ив нашем примере результат вычисления twice 4 есть 8 (разумеется!). Наконец, times применяется к 3, и затем результат этого применения применяется к 4, в результате чего получается 12. В этом последнем выражении подразумевается следующая расстановка скобок: (times 3) 4. Столь же свободно могут использоваться функции, получающие другие функции в качестве аргументов. Такие функции часто называют функционалами или операторами (но, опять подчеркиваем, в ML такая терминология может указывать только на содержательное использование функций, а не на какие-то особые их языковые свойства). Классическим примером функции такого рода является функция тар. Она получает в качестве аргументов функцию и список, и возвращает в качестве результата список, полученный из исходного применением функции-аргумента к каждому его элементу. Тип области определения функции-аргумента должен совпадать с типом элементов списка, но тип ее области значений произволен. Вот ее определение на ML: -fun map f nil = nil I map f (hd::tl) = f(hd) :: map f tl; >val map = fn : (a->b) -> (a list) -> (b list) Обратите внимание на то, что тип тар отражает связь между типом области определения функции-аргумента и типом элементов списка-аргумента, а также между типом области значений функции-аргумента и типом элементов списка-результата. Вот несколько примеров использования функции тар: -val 1st = [1,2,3,4,5]; >val 1st = [1,2,3,4,5] : int list -map twice 1st; >[2,4,6,8,10] : int list -fun listify x = [x]; >val listify = fn : a -> a list -map listify 1st; >[[1], [2], [3], [4], [5]] : int list list Упражнение 2.5.7 Определите функцию powerset, которая получает в качестве аргумента множество (представленное списком) и возвращает в качестве результата множество всех его подмножеств. Сочетая возможность рассмотрения функций как значений и возможность возвращать в качестве результата функцию, мы можем определить функцию, которая строит композицию двух других функций: -fun compose (f, g) (x) = f(g(x)); >val compose = fn : (a->b * c->a) -> Cc->b) -val fourtimes = compose (twice, twice); >val fourtimes = fn : int -> int -fourtimes 5; >20 : int Давайте рассмотрим этот пример внимательно. Функция compose получает в качестве аргумента пару функций (f ,g) и возвращает в качестве результата функцию; эта функция, будучи применена к аргументу х, возвращает в качестве результата f (g(x)). Поскольку результат есть f (g(x)), тип х должен быть типом области определения g; поскольку f применяется к g(x), тип области определения f должен совпадать с типом области значений g. Таким образом мы получаем тип compose, который был сообщен ML-системой. Функция fourtimes получается путем применения compose к паре функций (twice .twice). Результатом будет функция, которая, будучи применена к х, возвратит twice (twice (х)); в нашем случае, когда х есть 5, результатом является 20. Теперь, когда вы ближе познакомились с функциями в ML, вы можете заметить на данном этапе определенную асимметрию между функциональными значениями и значениями других типов: у нас пока нет никаких способов записи выражений, вырабатывающих функции непосредственно; единственный способ получения функции - это привязка идентификатора к функциональному значению. Но почему должно требоваться, чтобы каждая функция имела имя? В определенных случаях это удобно, но есть также ситуации, в которых удобно использовать безымянные функции, или лямбда-выражения (последний термин восходит к LISPy и Л-исчислению). Такие средства имеются в ML, и ниже приводятся примеры их использования: -fun listify х = [х]; >val listify = fn : a -> a list -val listify2 = fn x => [x]; >listify2 = fn : a -> a list -listify 7; >[7] : int list -listify2 7; >[7] : int list -(fn x => [x]) (7); >[7] : int list -val 1st = [1, 2, 3] ; >val 1st = [1, 2, 3] : int list -map (fn x => [x], 1st ); >[[1], [2], [3]]: int list list |
Среды: 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 | ||