- •Лабораторная работа №1, 2
- •Основы работы с интерпретатором Hugs
- •Арифметика
- •Кортежи
- •Функции
- •Условные выражения
- •Функции многих переменных и порядок определения функций
- •Ознакомьтесь со следующими функциями:
- •Индивидуальные задания к лабораторной работе №1:
- •Порядок выполнения лабораторной работы:
- •Лабораторная работа №2 «Структура списков и стандартные функции обработки списков»
- •Ход работы:
- •Индивидуальные задания к лабораторной работе №2:
- •Порядок выполнения лабораторной работы:
Лабораторная работа №2 «Структура списков и стандартные функции обработки списков»
Цель лабораторной работы: ознакомиться со структурой списков и с основными функциями работы со списками в Haskell. Выполнить индивидуальные задания и составить отчёт.
Ход работы:
Списки – одна из основных структур данных в функциональных языках. Они служат заменой массивов (хотя в современных языках обычно поддерживаются и массивы). По сути, список – просто последовательность элементов. В Haskell’е списки формируются следующим образом.
Как и другие структуры данных, списки формируются с помощью конструкторов. Для списков существует два конструктора: конструктор пустого списка, обозначаемый через «[]» и конструктор непустого списка, обозначаемый через «:». Пустой список – это список, не содержащий ни одного элемента. Непустой список содержит, по крайней мере, один элемент и всегда образуется из двух частей: головы (head) и хвоста (tail). Голова – это первый (самый левый) элемент списка, а хвост – список, состоящий из всех остальных элементов исходного списка. Списки всегда строятся слева, т.е. присоединение головы производится слева.
Таким образом, список [1,2,3] реально представлен в виде:
1 : (2 : ( 3 : []))
(Операторы «:» и «[]» соответствуют cons и nil в языке Lisp.)
Конструкторы «:» используются как для конструирования списков, так и в образцах, иллюстрацию к чему можно будет видеть в последующих примерах функций обработки списков. Знаком ☼ помечены функции, входящие в стандартную библиотеку.
☼ Вычисление длины списка.
length :: [t] -> Int
length [] = []
length (x:xs) = 1 + length xs
☼ Получение головы списка
head :: [a] -> a
head (x : _) = x
head [] = error "head : empty list!"
☼ Хвост списка
tail :: [a] -> [a]
tail (_:xs) = xs
tail [] = error "tail : empty list!"
☼ Последний элемент списка
last :: [a] -> a
last [x] = x
last (_:xs) = last xs
last [] = error "last : empty list!"
☼ Проверка списка на пустоту
null :: [a]->Bool
null [] = True
null (_:_) = False
Копирование списка (тождественное преобразование)
copy :: [a]->[a]
copy [] = []
copy (x:xs) = x : copy xs
Объединение двух списков
append :: [a]->[a]->[a]
append [] ys = ys
append (x:xs) ys = x : append xs ys
☼ xs++ys ≡ append xs ys
Обращение списка (изменение порядка элементов на обратный)
rev :: [a]->[a]
rev [] = []
rev (x:xs) = (rev xs)++ys
rev2 :: [a]->[a]->[a]
rev2 [] ys = ys
rev2 (x:xs) ys = rev2 xs (x:ys)
☼ reverse xs = rev2 xs []
☼ Получить первые n элементов списка
take :: Int -> [a] -> [a]
take n _ | n <= 0 = []
take _ [] = []
take n (x:xs) = x : take (n-1) xs
Получить n-ый элемент списка
nth :: Int->[a]->a
nth 1 (x:_) = x
nth n (x:xs) | n>1 = nth (n-1) xs
nth _ _ = error “nth: error…”
Вставка элемента в упорядоченный (отсортированный) список
insert :: Int->[Int]->[Int]
insert n [] = [n]
insert n (x:xs) = if n<=x then n:x:xs else x : insert n xs
insert n [] = [n]
insert n (x:xs) | n<=x = n:x:xs else x : insert n xs
insert n (x:xs) | n>x = insert n xs
Объединение двух упорядоченных списков
appendsort :: [Int]->[Int]->[Int]
appendsort xs [] = xs
appendsort (x:xs) ys = insert x (appendsort xs ys)
