- •1. Поколения языков программирования.
- •2.Понятие фп, история развития.
- •1 . Трактовка функции через понятие переменная
- •2. Определения без переменных:
- •3.Программирование при помощи функций.
- •4. Программирование при помощи процедур.
- •5. Символьные данные в строго-функциональных языках.
- •6.Элементарные селекторы, конструкторы и предикаты.
- •7. Рекурсивные функции.
- •8. Проблема выбора подфункции
- •9. Накапливающий параметр — аккумулятор
- •10. Локальное определение.
- •11. Функции высших порядков.
- •12. Фвп применительно к языку Haskell.
- •13. Основы лямбда исчисления
- •14. Правило преобразования лямбда выражения.
- •15. Ромбическое свойство системы редукций.
- •16. Стандартные порядки редукций.
- •18. Структуры данных и их типы на языке Haskell.
- •1. Синонимы типов
- •19. Понятие модуля в Haskell.
- •Абстрактные типы данных
- •Другие аспекты использования модулей
- •20. Классы и их экземпляры в Haskell.
- •21. Наследование в языке Haskell.
- •22. Сорта типов и структуры данных.
- •[Править]Определение
- •[Править]Примеры
7. Рекурсивные функции.
Рекурсия в программировании — задание алгоритма вычисления функции с использованием вызова её самой.
пример:
inv::[a]->[a]
inv[]=[]
inv(x:xs)=inv xs ++ [x]
8. Проблема выбора подфункции
Функциональная программа – множество функций, одна из которых рассматривается как первопричина для других – эта функция является главной, остальные функции служат для нее подпрограммами.
От удачного решения проблемы выбора подфункции зависит эффективность программы в целом.
Функция инверсия списка.
x |
обратить(x) |
(ABС) |
(СВА) |
((AB)(CD)) |
((CD)(АВ)) |
NIL |
NIL |
Для решения необходимо иметь функцию, которая могла бы поместить голову списка car (x) в конец рекурсивного вызова обратить (cdr (x))
добавить (x,y) – делает у новым послед. элементом х
-
x
у
добавить (x,y)
(AB)
С
(АВС)
Обратить (х)
1. х = NIL обратить (x)=NIL
2. х ≠ NIL , пусть обратить (cdr(x))=z, тогда обратить (х)=добавить (z,cdr(x))
1) обратить (х) = если равно (x,NIL) то NIL иначе добавить (обратить (cdr (x),car (x))
Добавить (х)
1. х = NIL добавить (x,y)=cons (y,NIL)
2. х ≠ NIL , пусть добавить (cdr(x),y)=z, тогда добавить (х,y)=cons (car (x),z)
1) добавить (x,y) ≡ если равно (x,NIL) то cons (y,NIL) иначе cons (car (x), добавить (cdr (x),y)
2) добавить (x,y) ≡ соединить (x, cons (y,NIL))
cons (y,NIL) – [y]
3) обратить (х) ≡ если равно (x,NIL) то NIL иначе соединить (обратить (cdr (x)), cons (car (x), NIL))
Например, задача разбиения предложения на слова и подсчет количества повторения каждого
можно разбить на функции по шагам:
разбиение на слова
удаление повторений слова, количество вхождений которого уже подсчитано
формирование массива кортежей (слово, колич вхождений)
забыла там еще - непосредственно функция подсчета повторений слова
то есть 4 функции
а можно например по другому:
1разбиваем на слова ,
2 считаем колич вхождений и сразу удаляем повторения для посчитанного слова, и выводим кортеж для конкретного слова (слово, колич вхождений)
итого 2 функции
9. Накапливающий параметр — аккумулятор
Основная идея состоит в том, чтобы определить вспомогательную функцию с лишним параметром, который используется для накапливания требуемого результата.
обратить (х)
обр (x,y), где х – инвертируемый список, у – параметр, накапливающий инвертированный список.
х :: [1,2,3,4,5] – начальн.
y:: [ ]
х :: [1,2,3,4,5] – 1 шаг
y:: [ ]
х :: [2,3,4,5] – 2 шаг
y:: [1]
х :: [3,4,5] – 3 шаг
y:: [ 2,1]
х :: [4,5] – 4 шаг
y:: [3,2,1]
обр (x,y) ≡ если равно (x,NIL) то y иначе обр (cdr (x), cons (car (x),y)
обратить (x) ≡ обр (x,NIL)
Применим метод накапливающих параметров в случае, когда необходимо накопить более чем 1 результат.
Бывает так, что при выполнении функции исключительно сёрьезно встаёт проблема расхода памяти. Эту проблему можно пояснить на примере функции, вычисляющей факториал числа:
Если
провести пример вычисления этой функции
с аргументом
,
то можно будет увидеть следующую
последовательность:
==>
==>
==>
==>
==>
==>
==>
На примере этого вычисления наглядно видно, что при рекурсивных вызовах функций очень сильно используется память. В данном случае количество памяти пропорционально значению аргумента, но аргументов может быть большее число. Возникает резонный вопрос: можно ли так написать функцию вычисления факториала (и ей подобные), чтобы память использовалась минимально?
Чтобы ответить на данный вопрос положительно, необходимо рассмотреть понятие аккумулятора (накопителя). Для этого можно рассмотреть следующий пример:
Пример 10. Функция вычисления факториала с аккумулятором.
В этом
примере второй параметр функции
выполняет
роль аккумулирующей переменной, именно
в ней содержится результат, который
возвращается по окончании рекурсии.
Сама же рекурсия в этом случае принимает
вид «хвостовой», память при этом
расходуется только на хранение адресов
возврата значения функции.
