- •Оглавление
- •От автора
- •Структура
- •Пояснения и обозначения
- •Демонстрация кунг-фу
- •Теория Основные понятия и типы данных
- •Кортежи
- •Функции, операторы
- •Полиморфные типы данных
- •Чтение сигнатур типов
- •Простейшие функции и операторы
- •Арифметические функции
- •Логические функции
- •Списочные функции
- •Кортежные функции
- •Создание своих функций
- •Способ 1. Определение функции как выражения от параметров:
- •Способ 2. Несколько определений одной функции:
- •Способ 3. Определение функции через синоним:
- •Способ 4. Лямбда функция (анонимная функция):
- •Способ 5. Частичное применение функции:
- •Образцы и сопоставление с образцом
- •Синтаксический хлеб и синтаксический сахар
- •Условия и ограничения
- •Локальные определения
- •Двумерный синтаксис
- •Арифметические последовательности
- •Замыкания списков
- •Функциональное мышление
- •Рекурсия как основное средство
- •Ручная редукция выражений
- •Думаем функционально, шаг раз
- •Думаем функционально, шаг два: аккумуляторы
- •Реализация простейших списочных и прочих функций
- •Думаем функционально, шаг три: хвостовая рекурсия
- •Еще раз о рекурсии
- •Полезные хитрости языка
- •Ленивые вычисления и строгие функции
- •Бесконечные списки
- •Функция show
- •Совсем немного о классах
- •Функция read
- •Функция error
- •Побочные эффекты и функция trace
- •Функции высших порядков
- •Мотивация
- •Функция map
- •Функция filter
- •Композиция функций
- •Функция foldr
- •Функция foldl
- •Свертки: разбор полетов
- •Выявление общей функциональности
- •Стандартные функции высших порядков
- •Еще немного про строгие функции
- •Создание своих типов данных
- •Простые перечислимые типы данных
- •Контейнеры
- •О сравнении, отображении и прочих стандартных операциях
- •Параметрические типы данных
- •Сложные типы данных
- •Тип данных Maybe
- •Рекурсивные типы данных: списки
- •Рекурсивные типы данных: деревья
- •Ввод-вывод
- •Простейший ввод-вывод
- •Объяснение кухни
- •Пример программы, производящей нетривиальное преобразование текстового файла
- •Пример решения задачи: Поиск в пространстве состояний
- •Через массивы и последовательность промежуточных состояний
- •Решение для тех, кто не хочет разбираться сам
- •Через списки, лог истории и уникальную очередь
- •Решение для тех, кто не хочет разбираться сам
- •Задачник
- •Пояснения и обозначения
- •Лабораторная работа 1 Простейшие функции
- •Простейшие логические функции
- •Простейшие списочные функции
- •Лабораторная работа 2 Символьные функции
- •Простейшие кортежные функции
- •Теоретико-множественные операции
- •Сортировка
- •Арифметические последовательности
- •Генераторы списков
- •Лабораторная работа 4 Бесконечные списки
- •Ввод-вывод
- •Нетривиальные функции
- •Лабораторная работа 5 Простые числа и факторизация
- •Деревья
- •Деревья вычислений
- •Дополнительные задания для самостоятельной работы Задания с Project Euler
- •Простейший инструментарий Установка WinHugs и начало работы
- •Работа с интерпретатором WinHugs в интерактивном режиме
- •Команды интерпретатору
- •Работа с модулями
- •Список рекомендуемой литературы и электронных ресурсов
Лабораторная работа 1 Простейшие функции
Запросите в интерпретаторе и объясните тип функций, проверьте их поведение на примерах входных данных:
(+), (-), (*), (/), div, mod, (^)
Запросите в интерпретаторе и объясните тип функций, проверьте их поведение на примерах входных данных, и напишите свою реализацию каждой функции под другим именем (например, под именами sumMy, productMy, и т.д.):
sum, product
max, min
maximum, minimum
even, odd
gcd, lcm (greatest common divisor, least common multiple)
(^)
Напишите функцию factMy :: Integer -> Integer, которая вычисляет факториал заданного числа, с помощью простой рекурсии.
Напишите функцию fibMy :: Integer -> Integer, которая вычисляет заданное по номеру число Фибоначчи с помощью простой рекурсии. Найдите, какое максимально большое число позволяет вам найти ваша система. Объясните, почему рекурсия так долго работает.
Попробуйте придумать более эффективную функцию вычисления числа Фибоначчи в виде рекурсивной функции вида fibMy' n prev prevprev = ..., которая принимает в качестве параметров предыдущее и пред-предыдущее число Фибоначчи.
Простейшие логические функции
Запросите в интерпретаторе и объясните тип функций, проверьте их поведение на примерах входных данных:
(>), (<), (==), (/=), (>=), (<=), (&&), (||), not
Запросите в интерпретаторе и объясните тип функций, проверьте их поведение на примерах входных данных, и напишите свою реализацию каждой функции под другим именем:
and, or
Простейшие списочные функции
Запросите в интерпретаторе и объясните тип функций, проверьте их поведение на примерах входных данных:
(:), null
Запросите в интерпретаторе и объясните тип функций, проверьте их поведение на примерах входных данных, и напишите свою реализацию каждой функции под другим именем:
head, tail
last, init
length, (!!), (++), concat
take, drop
reverse, elem, replicate
Напишите функцию lookupMy :: Eq a => a -> b -> [(a, b)] -> b, которая берет значение xa типа a, значение xb типа b, список кортежей [(a, b)], находит кортеж, в котором первый элемент равен xa, и выводит второй элемент этого кортежа. Если такого кортежа не нашлось, функция должна вернуть xb.
Напишите функцию substrMy :: [a] -> Int -> Int -> [a], которая возвращает все элементы списка начиная с какого-то и заканчивая каким-то с помощью функций take и drop.
Напишите функцию strReplaceMy :: Eq a => [a] -> [a] -> [a], которая принимает три списка и заменяет в третьем списке все вхождения первого списка на второй список с помощью функций length, (==), take и drop.
Напишите функцию elemIndices :: Eq a => a -> [a] -> [Int], которая находит, под какими индексами в списке встречается заданный элемент.
Напишите функцию strPosMy :: Eq a => [a] -> [a] -> [Int], которая находит все вхождения первого списка во второй и возвращает список номеров элементов, с которых эти вхождения начинаются с помощью функций length, (==), take и drop.
Напишите функцию strRotateMy :: [a] -> Int -> [a], которая производит заданное количество поворотов заданного списка. Операция кругового поворота над списком заключается в том, что последний элемент списка переносится в его начало. Например, strRotate [1,2,3,4,5,6] 2 = [5,6,1,2,3,4].
Напишите функцию unevenHandWritingMy :: String -> String, которая берет строку и возвращает ее же, но каждая третья буква должна стать прописной, если была строчной и наоборот.