- •1.1 Знакомство с интерпретатором Hugs.
- •1.2 Выполнение математических операций в интерпретаторе.
- •1.3. Простейшие генераторы списков.
- •1.4 Логические функции, функции сравнения, функции работы с перечислимыми типами данных.
- •1.5 Простейшие списочные и кортежные функции.
- •Задание на лабораторную работу №1.
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Пример выполнения лабораторной работы 1.
- •Лабораторная работа 2. Создание простейших рекурсивных программ. Функции работы со строками и множествами. Сообщения об ошибках и преобразования типов.
- •2.1 Создание простейших рекурсивных программ.
- •2.2 Функции работы со строками и множествами.
- •2.3 Сообщения об ошибках и преобразования типов
- •Задание на лабораторную работу 2.
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Пример выполнения работы
- •Лабораторная работа 3. Функции высших порядков.
- •Задание на лабораторную работу 3.
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Лабораторная работа 4. Текстовые файлы. Факторизация, простые числа, разные задачи.
- •4. 1 Работа с текстовыми файлами в Haskell
- •Задание на лабораторную работу 4.
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Лабораторная работа 5. Управление выводом в Прологе. Простейшие рекурсивные программы.
- •5.1 Факты и правила. База знаний. Запросы.
- •5.2 Управление выводом.
- •5.3 Рекурсия
- •Задание на лабораторную работу 5.
- •Вариант 1
- •Вариант 2
- •Вариант 3
- •Вариант 4
- •Вариант 5
- •Вариант 6
- •Вариант 7
- •Вариант 8
- •Вариант 9
- •Вариант 10
- •Лабораторная работа №6. Работа со списками в Прологе.
- •6.1 Списки в Прологе.
- •6.2 Алгоритмы обработки списков
- •6.3 Алгоритмы сортировки
- •Лабораторная работа № 7. Решение логических задач на Прологе.
- •Пример выполнения работы.
- •Лабораторная работа № 8.
Лабораторная работа 3. Функции высших порядков.
Функции высших порядков являются отличительной особенностью функционального программирования. Кратко дать определение функции высшего порядка можно так – это функция, имеющая аргументами другие функции или возвращающая в качестве результата другую функцию.
Рассмотрим сначала две функции, являющиеся предикатами, то есть возвращающими логические значения. Функция any имеет два аргумента и проверяет, содержит ли второй аргумент – список хотя бы один элемент, удовлетворяющий первому аргументу. Первый аргумент этой функции сам является функцией, возвращающей логическое значение.
Функция all проверяет выполнение первого аргумента для всех элементов своего второго аргумента:
Первый аргумент может быть некоторой встроенной функций, функцией, определенной пользователем, лямбда-функцией или локальной функцией, вводимой с помощью where. Далее при разборе заданий лабораторной работы продемонстрированы все эти возможности.
Одной из важнейших функций высшего порядка является функция map, встречающаяся во всех функциональных языках и даже в декларативных, таких как C++, Ruby, Python и других. Эта функция применяет свой первый аргумент – функцию последовательно к каждому элементу второго аргумента – списка. Вот примеры её вызова:
Функция filter оставляет во втором аргументе списке только элементы, удовлетворяющие первому аргументу – предикату:
Функция zip, вообще говоря, не являющаяся функцией высшего порядка, позволяет из двух списков создать список кортежей, объединяющих попарно элементы списков:
Заметьте, что длина результирующего списка будет равна длине кратчайшего из списков аргументов. Если же списки у нас одного типа, то к ним можно применить функцию высшего порядка zipWith, которая применяет свой первый аргумент-функцию к каждой паре элементов второго и третьего аргументов – списков:
Функцией, производящей обратное к zip преобразование, является функция unzip:
Комбинируя эти функции, можно решать задачи, связанные с обработкой индексов элементов списка. Например, получение списка индексов четных элементов числового списка:
Функция $ понижает приоритет функции, в данном примере использована как замена вложенных скобок. Функция (.) означает композицию функций в математическом смысле, её определение в Haskell:
В модуле List, впрочем, определены функции, упрощающие решение упомянутых задач. Приведем несколько примеров без подробного описания функций, в большинстве случаев из примера ясно, как работает функция.
Также в модуле List определена функция sort, сортирующая числовой список в порядке неубывания. Но во многих случаях требуется сортировать более сложные структуры данных, чем простой список. В этом случае надо воспользоваться функцией высшего порядка sortBy, первым аргументом которой будет функция сравнения. Например, для сортировки списка строк по длине можно написать так:
Здесь в качестве первого аргумента написана лямбда-функция, указывающая, как именно надо сравнивать два аргумента. Данную функцию следует использовать при выполнении задания 6 лабораторной работы.
Аналогично, существуют функции высшего порядка nubBy, deleteBy, deleteFirstsBy (By-вариант \\), unionBy, intersectBy, groupBy, sortBy, insertBy, maximumBy, minimumBy. Например, для удаления из списка кортежей элементов с повторяющейся суммой можно использовать:
При выполнении третьего задания данной лабораторной работы будут полезны функции высшего порядка из модуля Prelude, позволяющие разбивать или делить список на части по какому-либо условию, приведенные в таблице 3.1.
Таблица 3.1. Функции высшего порядка разделения списка.
Описание |
Имя функции |
Пример |
Получает список первых элементов, удовлетворяющих условию |
takeWhile |
|
Отбрасывает первые элементы, удовлетворяющие условию |
dropWhile |
|
Разбивает список на кортеж двух списков – первый содержит первые элементы, удовлетворяющие условию, второй – все остальные элементы |
span |
|
Разбивает список на кортеж двух списков – в первом первые элементы, не удовлетворяющие условию, во втором – все остальные элементы |
break |
|
Разбивает список на кортеж двух списков – в первом первые n элементов, во втором – все остальные элементы |
splitAt |
|
Среди функций высшего порядка модуля Prelude есть несколько функций, называемых свертками. Они позволяют применять функцию-параметр последовательно к элементам списка. В зависимости от порядка применения функции к аргументу-списку есть левая и правая свертки. Многие стандартные функции, например, sum, product, maximum, minimum, reverse определены с помощью функций-сверток. Ознакомьтесь с ними в таблице 3.2.
Таблица 3.2. Функции-свертки.
Описание |
Имя функции |
Пример |
Примечание |
Правая свертка с аккумулятором |
foldr |
|
foldr f a [x1,x2,..,xn] = =f x1 (f x2 (..(f xn a))..) foldr (-) 20 [2,5,3] = 2-(5-(3-20)) |
Левая свертка с аккумулятором |
foldl |
|
foldl f a [x1,x2,..,xn] = =f (f (f a x1) x2)..) xn) foldl (-) 20 [2,5,3] = ((20-3)-5)-2 |
Правая свертка |
foldr1 |
|
foldr f a [x1,x2,..,xn] = =f x1 (f x2 (..(f xn-1 xn ))..) foldr1 (-) [20,5,3] = (20-(5-3)) |
Левая свертка |
foldl1 |
|
foldl f a [x1,x2,..,xn] = =f (f (f x1 x2) x3)..) xn) foldl1 (-) [20,5,3] = ((20-5)-3) |
При выполнении заданий 5 и 7 следует помнить, что в Haskell можно работать с функциями, как с данными. Функции могут быть элементами списков или кортежей и подвергаться применению списочных или кортежных функций. При вызове функций с аргументами–функциями последние могут заключаться в круглые скобки. Например, применение каждой из списка функций к аргументу 5:
.