SlideShare a Scribd company logo
ФУНКЦИОНАЛЬНОЕ ПРОГРАММИРОВАНИЕ
2
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Глава 1. Элементы функционального программирования
 Архитектура фон Неймана диктует стиль программирования?
 Средства программирования:
 Арифметические и логические операции;
 Присваивания;
 Последовательное исполнение шагов алгоритма;
 Управление (управляющие конструкции);
 Процедуры и функции;
 Модули, исключительные ситуации, структуры данных,...
 Программа: описание процесса (алгоритма) или «черный ящик»?
Действие
Выбор
Если «да» Если «нет»
Алгоритм
«Черный ящик»
Вход Выход
Функция
1.1. Введение в функциональное программирование
3
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Задача о вычислении значений квадратных корней уравнения
(процедурный стиль программирования)
/** Процедура вычисляет вещественные или комплексные корни квадратного трехчлена,
* в предположении, что первый коэффициент (a) отличен от нуля.
* Аргументы: a, b, c – коэффициенты квадратного трехчлена;
* Результаты: complexFlag – признак комплексных корней;
* r1, r2 – вещественные корни, если complexFlag = False и
* вещественная и мнимая части двух корней, если complexFlag = True
*/
class Result { boolean complexFlag; double r1; double r2; }
static double discriminant (double a, double b, double c) {
return b * b – 4 * a * c;
}
static Result squareRoots (double a, double b, double c) {
Result result = new Result();
double discr = discriminant (a, b, c); // Вычисляем дискриминант
result.complexFlag = discr < 0; // Определяем, вещественные или мнимые корни
if (result.complexFlag) {
result.r1 = (-b) / (2*a); // Вещественная часть корней
result.r2 = Math.sqrt(-discr) / (2*a); // Мнимая часть корней
} else {
result.r1 = (-b + Math.sqrt(discr)) / (2*a); // Первый вещественный корень
result.r2 = (-b – Math.sqrt(discr)) / (2*a); // Второй вещественный корень
}
return result;
}
4
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Та же программа, написанная в функциональном стиле программирования
(на псевдоязыке с Java-подобным синтаксисом)
/** Функция вычисляет вещественные или комплексные корни квадратного трехчлена,
* в предположении, что первый коэффициент (a) отличен от нуля.
* Аргументы: a, b, c – коэффициенты квадратного трехчлена;
* Результаты: признак комплексных корней;
* вещественные корни, если они вещественные, и
* вещественная и мнимая части двух корней, если мнимые
*/
double discriminant (double a, double b, double c) {
return b * b – 4 * a * c;
}
(boolean, double, double) squareRoots (double a, double b, double c) {
final double discr = discriminant(a, b, c); // Значение дискриминанта
final double complexFlag = discr < 0; // Определяем, вещественные или мнимые корни
(complexFlag,
(complexFlag ? ((-b) / (2*a), sqrt(-discr) / (2*a))
: ((-b + sqrt(discr)) / (2*a), (-b – sqrt(discr)) / (2*a))
);
}
5
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Особенности этой программы
Вместо переменных и
присваиваний
используются константы
Составные значения легко
описываются...
...и создаются
Широко используются
условные выражения
Константы получают
динамически
вычисляемые значения
Тело функции представляет собой
суперпозицию применений функций для
описания функциональной зависимости
результата от входных данных
Результаты не зависят от
порядка вычислений
(возможны параллельные
вычисления)
double discriminant (double a, double b, double c) {
return b * b – 4 * a * c;
}
(boolean, double, double) squareRoots (double a, double b, double c) {
final double discr = discriminant(a, b, c); // Значение дискриминанта
final double complexFlag = discr < 0; // Определяем, вещественные или мнимые корни
(complexFlag,
(complexFlag ? ((-b) / (2*a), sqrt(-discr) / (2*a))
: ((-b + sqrt(discr)) / (2*a), (-b – sqrt(discr)) / (2*a))
);
}
6
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Функциональное представление множеств
boolean intSet (int); // описание функционального типа данных
boolean emptySet (int n) { return false; } // пустое множество
boolean oddSet (int n) { return n % 2 == 1; } // множество нечетных чисел
Несколько полезных операций над множествами
intSet addElement (intSet s; int newElem) {
boolean newSet (int n) { return s(n) || (n == newElem); }
return newSet;
}
intSet buildInterval (int min, int max) {
boolean newSet (int n) { return (n >= min) && (n <= max); }
return newSet;
}
intSet difference (intSet s1, intSet s2) {
boolean newSet (int n) { return s1(n) && ! s2(n); }
return newSet;
}
Будут ли работать эти операции?
7
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Попробуем вычислить выражение
difference (oddSet, addElement (emptySet, 3)) (7) { Принадлежит ли 7 множеству [odds]  [3] }
addElement
s = emptySet
newElem = 3
boolean emptySet (int n) { return false; }
intSet addElement (intSet s, int newElem) {
boolean newSet (int n)
{ return s(n) || (n == newElem); }
return newSet;
}
boolean oddSet (int n) { return n % 2 == 1; }
intSet difference (intSet s1, intSet s2) {
boolean newSet (int n) { return s1(n) && ! s2(n); }
return newSet;
}
Стек вычислений
newSet
s2 = addElement.newSet
s1 = oddSet
difference
newSet
8
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Функциональное представление множеств в языке Java
В языке Java все же можно построить правильную программу для работы с функциональным
представлением множеств:
abstract class IntSet {
abstract boolean has(int elem);
public static IntSet addElement(final IntSet s, final int n) {
return new IntSet() {
public boolean has(int elem) { return elem == n || s.has(elem); }
};
}
public static IntSet buildInterval(final int n, final int m) {
return new IntSet() {
public boolean has(int elem) { return elem >= n && elem <= m; }
};
}
public static IntSet difference(final IntSet s1, final IntSet s2) {
return new IntSet() {
public boolean has(int elem) { return s1.has(elem) && ! s2.has(elem); }
};
}
public static void main(String[] args) {
IntSet emptySet = new IntSet() { public boolean has(int e) { return false; }};
IntSet oddSet = new IntSet() { public boolean has(int e) { return e % 2 == 1; }};
System.out.println(difference(oddSet, addElement(emptySet, 3)).has(7));
}
}
9
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Подведение итогов
 Императивные языки служат для описания процессов; функциональные – для описания
функций, вычисляющих результат по исходным данным.
 На традиционных языках можно писать в функциональном стиле, однако средств работы с
функциями в традиционных языках недостаточно или они неудобны.
 Традиционные способы реализации языков программирования плохо подходят для
программ, написанных в функциональном стиле.
 Традиционные языки не могут обеспечить удобных средств для распараллеливания
вычислений: последовательное выполнение команд – узкое место традиционной
архитектуры компьютеров («фон-Неймановское горлышко»).
 Для функционального программирования требуются специализированные языки
10
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Литература
Основная
Дополнительная
1. А. Филд, П. Харрисон. Функциональное программирование. М.: Мир, 1993.
2. П. Хендерсон. Функциональное программирование. Применение и реализация.
М.: Мир, 1983.
3. А.А.Кубенский. Функциональное программирование. ИТМО, 2010.
1. Пол Хьюдак, Джон Петерсон, Джозеф Фасел. Мягкое введение в Haskell.
RSDN Magazin, 2006 № 4 и 2007 № 1
(http://rsdn.ru/article/haskell/haskell_part1.xml,
http://rsdn.ru/article/haskell/haskell_part2.xml)
2. Р. В. Душкин Функциональное программирование на языке Haskell (+ CD-ROM)
Издательство: ДМК Пресс, 2007 г., Мягкая обложка, 608 стр.
3. Н.А.Роганова. Функциональное программирование. Учебник для вузов, 2002.
4. Graham Hutton. Programming in Haskell. 2007 г., Мягкая обложка, 184 стр.
5. Bryan O'Sullivan, John Goerzen, Donald Stewart. Real World Haskell:
Code You Can Believe In. Издательство: O'Reilly Media, 2008 г., Мягкая обложка, 710 стр.
11
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
1.2. Введение в язык Haskell
История языка Haskell
 1960: John McCarthy, LISP – первый функциональный язык программирования
 1978: John Backus, FP – система комбинаторного программирования
 конец 1970-х: Edinburgh univ., ML – meta-language
 1985-1986: David Turner, Miranda – функциональный язык с «ленивыми» вычислениями
 начало 1930-х: Church, формализация функций в λ-исчислении
 1990: Ericsson, Erlang – «коммерческий» функциональный язык
 1988: Paul Hudak, Haskell – первая версия языка Haskell
 1999: Haskell group, Haskell’98 – «стандартная» версия языка Haskell
Haskell – чисто функциональный язык программирования, названный в честь
Хаскелла Карри (Haskell B. Curry – 1900-1982), известного, главным образом,
благодаря работам в области математической логики и комбинаторной логики в
конце 1950-х – начале 1960-х годов
http://haskell.org/onlinereport/index.html - пересмотренное сообщение о языке Haskell’98
http://haskell.org/tutorial - «Нежное» введение в Haskell
12
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Типы данных и базовые конструкции языка Haskell
Элементарные типы данных
 Integer, Int – целые значения (25, -17, 111222333444555666777888)
 Float, Double – вещественные значения (3.14, -2.718281828459045)
 Char – символьные значения ('A', '*', '3')
 Bool – логические значения (True, False)
Идентификаторы: fact, fAcToRiAl, fact_1, fact''
Знаки операций: +, -, *, <, ==
Идентификаторы применяются для обозначения констант – значений разных типов
(простых, составных, функций) и типов. Любому идентификатору можно
сопоставить тип и значение:
school :: Integer
school = 239
piHalf :: Double
piHalf = 3.1415926536 / 2
13
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Кортежи и функции
Значения могут объединяться в более сложные с помощью кортежирования.
Например:
pair :: (Double, Double)
pair = (2.7, 3.14)
attributes :: (Char, (Int, Int, Int), Bool)
attributes = ('M', (17, 4, 1955), True)
Тип функции определяется типами аргументов и результата, например:
sin :: Double -> Double -- аргумент и результат типа Double
plusInt :: Int -> Int -> Int -- два аргумента типа Int, результат Int
divMod :: (Int, Int) -> (Int, Int) -- аргумент и результат - кортежи
Выражения составляются из констант применением операций и функций, например:
result = sin (3.1416 / 4) - 2.5
c10 = 3 + plusInt 3 4
pair = divMod (1458, plusInt 176 192)
Операции и функции отличаются только формой записи. Следующие выражения
эквивалентны:
3 + 8 и (+) 3 8
27 `div` 4 и div 27 4
7 `plusInt` 11 и plusInt 7 11
14
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Определение функций с помощью уравнений
Уравнения задают правила, по которым происходит вычисление функции, то есть каким
образом результат получается из аргументов функции, например:
plusInt :: Int -> Int -> Int
plusInt a b = a + b
divMod :: (Int, Int) -> (Int, Int)
divMod (a, b) = (a `div` b, a `mod` b)
Уравнения могут содержать условные выражения и рекурсивные обращения, например:
factorial :: Integer -> Integer
factorial n = if n == 0 then 1
else n * (factorial (n-1))
sum :: Integer -> Integer
sum n = n + if n == 0 then 0 else sum (n-1)
factorial1 :: Integer -> Integer
factorial1 n | n == 0 = 1
| n > 0 = n * (factorial1 (n-1))
factorial2 :: Integer -> Integer
factorial2 0 = 1
factorial2 n = n * (factorial2 (n-1))
Уравнений для одной функции может быть несколько, тогда аргументы последовательно
сопоставляются с образцами:
15
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Подготовка и запуск программ
factorial :: Integer -> Integer
factorial n | n == 0 = 1
| n > 0 = n * (factorial (n-1))
В лекциях всюду используется «краткий» синтаксис, при котором каждое новое определение
начинается с новой строки. Этот синтаксис очень чувствителен к расположению строк.
Каждое новое «предложение» должно начинаться ровно в той же позиции, что и предыдущее.
Если требуется разместить «предложение» на нескольких строках, то «продолжения»
должны начинаться с отступом от позиции предыдущей строки
- ошибка
factorial :: Integer -> Integer
factorial n | n == 0 = 1
| n > 0 = n * (factorial (n-1))
- ошибка
Заметьте, что второе уравнение, в котором опущены имя функции и образец, синтаксически
является продолжением первого уравнения.
factorial :: Integer -> Integer
factorial n | n == 0 = 1 | n > 0 = n * factorial (n-1))
- нет ошибки
16
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Подготовка и запуск программ
«Полный» синтаксис подразумевает, что последовательность «предложений» заключается в
фигурные скобки, а отдельные предложения отделяются друг от друга точками с запятой. В
случае использования «полного» синтаксиса соблюдать отступы не обязательно.
{ factorial :: Integer -> Integer;
factorial n | n == 0 = 1
| n > 0 =
n * (factorial (n-1)) }
- нет ошибки
В программе можно смешивать полный и краткий синтаксис. Анализатор переключается
между ними по следующим правилам:
• анализ начинается в режиме полного синтаксиса;
• если там, где нужна открывающая фигурная скобка, ее нет, то она автоматически
вставляется, а анализатор переходит в режим краткого синтаксиса;
• если в режиме краткого синтаксиса очередная строка начинается с той же позиции, что и
начало всего предложения, то перед ней автоматически вставляется точка с запятой;
• если очередная строка начинается с отступом влево от начала текущего предложения, то
вставляется закрывающая фигурная скобка;
• если очередная строка начинается с отступом вправо, то это – продолжение предыдущей
строки (ничего не вставляется)
17
Исполнение программ с помощью текстовой подстановки
factorial :: Integer -> Integer
factorial n | n == 0 = 1
| n > 0 = n * (factorial (n-1))
factorial 3
3 * (factorial (3-1))
3 * (factorial 2)
3 * (2 * (factorial (2-1)))
3 * (2 * (factorial 1))
3 * (2 * (1 * (factorial (1-1))))
3 * (2 * (1 * (factorial 0)))
3 * (2 * (1 * 1))
6
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
18
Несколько определений простых арифметических функций
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
-- Вычисление наибольшего общего делителя двух натуральных чисел
gcd :: Integer -> Integer -> Integer
gcd m n | m < n = gcd n m
| n < 0 = error "gcd: Wrong argument"
gcd m 0 = m
gcd m n = gcd n (m `mod` n)
-- Проверка заданного натурального числа на простоту
prime :: Integer -> Bool
prime' :: Integer -> Integer -> Bool
prime p | p <= 0 = error "prime: Non-positive argument"
| otherwise = prime' 2 p
prime' d p | d * d > p = True
| p `mod` d == 0 = False
| otherwise = prime' (d+1) p
19
Немного о явных и неявных преобразованиях типов
Кубенский А.А. Функциональное программирование.
Глава 1. Элементы функционального программирования.
Язык Haskell – строго типизированный. Это означает, что во время компиляции тип любого
выражения известен и контролируется. Тем не менее, многие функции и операции допускают
в качестве аргументов (операндов) значения разных типов.
2 + 5 – сложение целых;
2.5 + 3.5 – сложение вещественных;
2 + 3.5 – сложение вещественных (первый операнд перед операцией преобразуется);
n + 3.5 where n = 2
– сложение вещественных (тип первого операнда «выводится» как вещественное);
fromIntegral n + 3.5 where { n :: Int; n = 2 }
– сложение вещественных (тип первого операнда явно преобразован);
a + b where { a :: Int; a = 2; b :: Integer; b = 12 }
– ошибка (операнды имеют разные типы);
n + 3.5 where { n :: Int; n = 2 }
– ошибка (тип первого операнда явно указан как целый);
a + fromIntegral b where { a :: Int; a = 2; b :: Integer; b = 12 }
– сложение коротких целых;
Некоторые функции преобразования типов:
• fromIntegral, fromRational, fromEnum,
• truncate, round, ceiling, floor

More Related Content

What's hot

PHP7 - что ожидать?
PHP7 - что ожидать?PHP7 - что ожидать?
PHP7 - что ожидать?
Дмитрий Золотов
 
Java. Переменные, типы данных, операторы
Java. Переменные, типы данных, операторыJava. Переменные, типы данных, операторы
Java. Переменные, типы данных, операторы
Unguryan Vitaliy
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
Igor Shkulipa
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программированияAlex.Kolonitsky
 
Урок 6. Чистое лямбда-исчисление.
Урок 6. Чистое лямбда-исчисление. Урок 6. Чистое лямбда-исчисление.
Урок 6. Чистое лямбда-исчисление.
Система дистанционного обучения MyDLS
 
Java. Методы
Java. Методы Java. Методы
Java. Методы
Unguryan Vitaliy
 
Java. Массивы. Многомерные массивы.
Java. Массивы. Многомерные массивы.Java. Массивы. Многомерные массивы.
Java. Массивы. Многомерные массивы.
Unguryan Vitaliy
 
Stream API
Stream APIStream API
Stream API
Unguryan Vitaliy
 
апкс 2011 04_verilog_продолж
апкс 2011 04_verilog_продолжапкс 2011 04_verilog_продолж
апкс 2011 04_verilog_продолжIrina Hahanova
 
Java. Строки. Класс String.
Java. Строки. Класс String.Java. Строки. Класс String.
Java. Строки. Класс String.
Unguryan Vitaliy
 
C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.
Igor Shkulipa
 
Reactive extensions
Reactive extensionsReactive extensions
Reactive extensions
Sergey Teplyakov
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8
chashnikov
 
Scala Magic, Alexander Podhaliusin
Scala Magic, Alexander PodhaliusinScala Magic, Alexander Podhaliusin
Scala Magic, Alexander Podhaliusin
Vasil Remeniuk
 
Ruby — Паттерны программирования
Ruby — Паттерны программированияRuby — Паттерны программирования
Ruby — Паттерны программирования
Evgeny Smirnov
 
Рекурсия. Поиск
Рекурсия. ПоискРекурсия. Поиск
Рекурсия. Поиск
Olexandra Dmytrenko
 
Основы языка Питон: типы данных, операторы
Основы языка Питон: типы данных, операторыОсновы языка Питон: типы данных, операторы
Основы языка Питон: типы данных, операторы
Theoretical mechanics department
 
Java. Cистемы счислния, битовые операции
Java. Cистемы счислния, битовые операцииJava. Cистемы счислния, битовые операции
Java. Cистемы счислния, битовые операции
Unguryan Vitaliy
 

What's hot (19)

PHP7 - что ожидать?
PHP7 - что ожидать?PHP7 - что ожидать?
PHP7 - что ожидать?
 
Java. Переменные, типы данных, операторы
Java. Переменные, типы данных, операторыJava. Переменные, типы данных, операторы
Java. Переменные, типы данных, операторы
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программирования
 
Урок 6. Чистое лямбда-исчисление.
Урок 6. Чистое лямбда-исчисление. Урок 6. Чистое лямбда-исчисление.
Урок 6. Чистое лямбда-исчисление.
 
Java. Методы
Java. Методы Java. Методы
Java. Методы
 
Java. Массивы. Многомерные массивы.
Java. Массивы. Многомерные массивы.Java. Массивы. Многомерные массивы.
Java. Массивы. Многомерные массивы.
 
Stream API
Stream APIStream API
Stream API
 
апкс 2011 04_verilog_продолж
апкс 2011 04_verilog_продолжапкс 2011 04_verilog_продолж
апкс 2011 04_verilog_продолж
 
Java. Строки. Класс String.
Java. Строки. Класс String.Java. Строки. Класс String.
Java. Строки. Класс String.
 
C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.
 
Reactive extensions
Reactive extensionsReactive extensions
Reactive extensions
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8
 
Scala Magic, Alexander Podhaliusin
Scala Magic, Alexander PodhaliusinScala Magic, Alexander Podhaliusin
Scala Magic, Alexander Podhaliusin
 
Ruby — Паттерны программирования
Ruby — Паттерны программированияRuby — Паттерны программирования
Ruby — Паттерны программирования
 
Рекурсия. Поиск
Рекурсия. ПоискРекурсия. Поиск
Рекурсия. Поиск
 
Основы языка Питон: типы данных, операторы
Основы языка Питон: типы данных, операторыОсновы языка Питон: типы данных, операторы
Основы языка Питон: типы данных, операторы
 
Java. Cистемы счислния, битовые операции
Java. Cистемы счислния, битовые операцииJava. Cистемы счислния, битовые операции
Java. Cистемы счислния, битовые операции
 
Python
PythonPython
Python
 

Viewers also liked

Функциональное программирование в браузере / Никита Прокопов
Функциональное программирование в браузере / Никита ПрокоповФункциональное программирование в браузере / Никита Прокопов
Функциональное программирование в браузере / Никита Прокопов
Ontico
 
Программирование доступное каждому
Программирование доступное каждомуПрограммирование доступное каждому
Программирование доступное каждому
Michael Akimov
 
Программирование и информационные технологии
Программирование и информационные технологииПрограммирование и информационные технологии
Программирование и информационные технологии
SPBU_RU UNIVERSITY
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
Alexander Granin
 
Новые тимбилдинги для жаркого лета 2014
Новые тимбилдинги для жаркого лета 2014Новые тимбилдинги для жаркого лета 2014
Новые тимбилдинги для жаркого лета 2014
Ведущий Сергей Пчела
 
Каждый пятый россиянин увидел улучшения в сфере ЖКХ: опрос ВЦИОМ
Каждый пятый россиянин увидел улучшения в сфере ЖКХ: опрос ВЦИОМКаждый пятый россиянин увидел улучшения в сфере ЖКХ: опрос ВЦИОМ
Каждый пятый россиянин увидел улучшения в сфере ЖКХ: опрос ВЦИОМ
Фонд капитального ремонта многоквартирных домов города Москвы
 
Сергей Бережной — Парное программирование
Сергей Бережной — Парное программированиеСергей Бережной — Парное программирование
Сергей Бережной — Парное программированиеYandex
 
Парное программирование
Парное программированиеПарное программирование
Парное программированиеLana Milanovich
 
Программирование как этап решения задач на компьютере
Программирование как этап решения задач на компьютереПрограммирование как этап решения задач на компьютере
Программирование как этап решения задач на компьютере
Andrey Dolinin
 
Шизофрения - полный курс лекций
Шизофрения - полный курс лекций Шизофрения - полный курс лекций
Шизофрения - полный курс лекций
Igor Kleiner
 
Кружок по робототехнике. Занятие #2. Программируем моторы
Кружок по робототехнике. Занятие #2. Программируем моторыКружок по робототехнике. Занятие #2. Программируем моторы
Кружок по робототехнике. Занятие #2. Программируем моторы
Alexander Kolotov
 
Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Dmitri Soshnikov
 
Кирилл Мокевнин — Ментальное программирование
Кирилл Мокевнин — Ментальное программированиеКирилл Мокевнин — Ментальное программирование
Кирилл Мокевнин — Ментальное программированиеDaria Oreshkina
 
Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»
DevDay
 
Что такое бренд и как его позиционировать
Что такое бренд и как его позиционироватьЧто такое бренд и как его позиционировать
Что такое бренд и как его позиционировать
Екатерина Мартынычева
 
Ответы на типовые вопросы возникающие в ходе эксплуатации УАИС Бюджетный учет
Ответы на типовые вопросы возникающие в ходе эксплуатации УАИС Бюджетный учетОтветы на типовые вопросы возникающие в ходе эксплуатации УАИС Бюджетный учет
Ответы на типовые вопросы возникающие в ходе эксплуатации УАИС Бюджетный учет
Департамент образования города Москвы
 
Мобильное программирование: Проведи лето с пользой
Мобильное программирование: Проведи лето с пользойМобильное программирование: Проведи лето с пользой
Мобильное программирование: Проведи лето с пользой
Департамент образования города Москвы
 
MCJ Edward Tufte Notes
MCJ Edward Tufte NotesMCJ Edward Tufte Notes
MCJ Edward Tufte Notes
McGarrah Jessee
 
FUTURE PERFECT PLATFORMS russian
FUTURE PERFECT PLATFORMS russianFUTURE PERFECT PLATFORMS russian
FUTURE PERFECT PLATFORMS russian
John Fitzpatrick
 
Visual Design Basics: The Building Blocks of a Great Slide
Visual Design Basics: The Building Blocks of a Great SlideVisual Design Basics: The Building Blocks of a Great Slide
Visual Design Basics: The Building Blocks of a Great Slide
Chiara Ojeda
 

Viewers also liked (20)

Функциональное программирование в браузере / Никита Прокопов
Функциональное программирование в браузере / Никита ПрокоповФункциональное программирование в браузере / Никита Прокопов
Функциональное программирование в браузере / Никита Прокопов
 
Программирование доступное каждому
Программирование доступное каждомуПрограммирование доступное каждому
Программирование доступное каждому
 
Программирование и информационные технологии
Программирование и информационные технологииПрограммирование и информационные технологии
Программирование и информационные технологии
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
Новые тимбилдинги для жаркого лета 2014
Новые тимбилдинги для жаркого лета 2014Новые тимбилдинги для жаркого лета 2014
Новые тимбилдинги для жаркого лета 2014
 
Каждый пятый россиянин увидел улучшения в сфере ЖКХ: опрос ВЦИОМ
Каждый пятый россиянин увидел улучшения в сфере ЖКХ: опрос ВЦИОМКаждый пятый россиянин увидел улучшения в сфере ЖКХ: опрос ВЦИОМ
Каждый пятый россиянин увидел улучшения в сфере ЖКХ: опрос ВЦИОМ
 
Сергей Бережной — Парное программирование
Сергей Бережной — Парное программированиеСергей Бережной — Парное программирование
Сергей Бережной — Парное программирование
 
Парное программирование
Парное программированиеПарное программирование
Парное программирование
 
Программирование как этап решения задач на компьютере
Программирование как этап решения задач на компьютереПрограммирование как этап решения задач на компьютере
Программирование как этап решения задач на компьютере
 
Шизофрения - полный курс лекций
Шизофрения - полный курс лекций Шизофрения - полный курс лекций
Шизофрения - полный курс лекций
 
Кружок по робототехнике. Занятие #2. Программируем моторы
Кружок по робототехнике. Занятие #2. Программируем моторыКружок по робототехнике. Занятие #2. Программируем моторы
Кружок по робототехнике. Занятие #2. Программируем моторы
 
Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...
 
Кирилл Мокевнин — Ментальное программирование
Кирилл Мокевнин — Ментальное программированиеКирилл Мокевнин — Ментальное программирование
Кирилл Мокевнин — Ментальное программирование
 
Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»
 
Что такое бренд и как его позиционировать
Что такое бренд и как его позиционироватьЧто такое бренд и как его позиционировать
Что такое бренд и как его позиционировать
 
Ответы на типовые вопросы возникающие в ходе эксплуатации УАИС Бюджетный учет
Ответы на типовые вопросы возникающие в ходе эксплуатации УАИС Бюджетный учетОтветы на типовые вопросы возникающие в ходе эксплуатации УАИС Бюджетный учет
Ответы на типовые вопросы возникающие в ходе эксплуатации УАИС Бюджетный учет
 
Мобильное программирование: Проведи лето с пользой
Мобильное программирование: Проведи лето с пользойМобильное программирование: Проведи лето с пользой
Мобильное программирование: Проведи лето с пользой
 
MCJ Edward Tufte Notes
MCJ Edward Tufte NotesMCJ Edward Tufte Notes
MCJ Edward Tufte Notes
 
FUTURE PERFECT PLATFORMS russian
FUTURE PERFECT PLATFORMS russianFUTURE PERFECT PLATFORMS russian
FUTURE PERFECT PLATFORMS russian
 
Visual Design Basics: The Building Blocks of a Great Slide
Visual Design Basics: The Building Blocks of a Great SlideVisual Design Basics: The Building Blocks of a Great Slide
Visual Design Basics: The Building Blocks of a Great Slide
 

Similar to Урок 1. Что такое функциональное программирование

C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.
Igor Shkulipa
 
лабораторная работа №5
лабораторная работа №5лабораторная работа №5
лабораторная работа №5Zhanna Kazakova
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
mcroitor
 
Алгоритмы и структуры данных осень 2013 лекция 8
Алгоритмы и структуры данных осень 2013 лекция 8Алгоритмы и структуры данных осень 2013 лекция 8
Алгоритмы и структуры данных осень 2013 лекция 8Technopark
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#
Dmitri Soshnikov
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"
Fwdays
 
Ecma script 6 in action
Ecma script 6 in actionEcma script 6 in action
Ecma script 6 in action
Yuri Trukhin
 
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
solit
 
Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.
Система дистанционного обучения MyDLS
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Dima Dzuba
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
Глеб Тарасов
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияYandex
 
парадигмы программирования и шаблоны проектирования
парадигмы программирования и шаблоны проектированияпарадигмы программирования и шаблоны проектирования
парадигмы программирования и шаблоны проектирования
moldovaictsummit2016
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Timur Safin
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуAndreyGeonya
 
Лекция 6
Лекция 6Лекция 6
Лекция 6itc73
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
Anton Arhipov
 
C# Desktop. Занятие 16.
C# Desktop. Занятие 16.C# Desktop. Занятие 16.
C# Desktop. Занятие 16.
Igor Shkulipa
 

Similar to Урок 1. Что такое функциональное программирование (20)

C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.
 
лабораторная работа №5
лабораторная работа №5лабораторная работа №5
лабораторная работа №5
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
 
Алгоритмы и структуры данных осень 2013 лекция 8
Алгоритмы и структуры данных осень 2013 лекция 8Алгоритмы и структуры данных осень 2013 лекция 8
Алгоритмы и структуры данных осень 2013 лекция 8
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#
 
лек5 6
лек5 6лек5 6
лек5 6
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"
 
Ecma script 6 in action
Ecma script 6 in actionEcma script 6 in action
Ecma script 6 in action
 
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
 
Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
 
JavaScript Intro
JavaScript IntroJavaScript Intro
JavaScript Intro
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знания
 
парадигмы программирования и шаблоны проектирования
парадигмы программирования и шаблоны проектированияпарадигмы программирования и шаблоны проектирования
парадигмы программирования и шаблоны проектирования
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногу
 
Лекция 6
Лекция 6Лекция 6
Лекция 6
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
C# Desktop. Занятие 16.
C# Desktop. Занятие 16.C# Desktop. Занятие 16.
C# Desktop. Занятие 16.
 

Урок 1. Что такое функциональное программирование

  • 2. 2 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Глава 1. Элементы функционального программирования  Архитектура фон Неймана диктует стиль программирования?  Средства программирования:  Арифметические и логические операции;  Присваивания;  Последовательное исполнение шагов алгоритма;  Управление (управляющие конструкции);  Процедуры и функции;  Модули, исключительные ситуации, структуры данных,...  Программа: описание процесса (алгоритма) или «черный ящик»? Действие Выбор Если «да» Если «нет» Алгоритм «Черный ящик» Вход Выход Функция 1.1. Введение в функциональное программирование
  • 3. 3 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Задача о вычислении значений квадратных корней уравнения (процедурный стиль программирования) /** Процедура вычисляет вещественные или комплексные корни квадратного трехчлена, * в предположении, что первый коэффициент (a) отличен от нуля. * Аргументы: a, b, c – коэффициенты квадратного трехчлена; * Результаты: complexFlag – признак комплексных корней; * r1, r2 – вещественные корни, если complexFlag = False и * вещественная и мнимая части двух корней, если complexFlag = True */ class Result { boolean complexFlag; double r1; double r2; } static double discriminant (double a, double b, double c) { return b * b – 4 * a * c; } static Result squareRoots (double a, double b, double c) { Result result = new Result(); double discr = discriminant (a, b, c); // Вычисляем дискриминант result.complexFlag = discr < 0; // Определяем, вещественные или мнимые корни if (result.complexFlag) { result.r1 = (-b) / (2*a); // Вещественная часть корней result.r2 = Math.sqrt(-discr) / (2*a); // Мнимая часть корней } else { result.r1 = (-b + Math.sqrt(discr)) / (2*a); // Первый вещественный корень result.r2 = (-b – Math.sqrt(discr)) / (2*a); // Второй вещественный корень } return result; }
  • 4. 4 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Та же программа, написанная в функциональном стиле программирования (на псевдоязыке с Java-подобным синтаксисом) /** Функция вычисляет вещественные или комплексные корни квадратного трехчлена, * в предположении, что первый коэффициент (a) отличен от нуля. * Аргументы: a, b, c – коэффициенты квадратного трехчлена; * Результаты: признак комплексных корней; * вещественные корни, если они вещественные, и * вещественная и мнимая части двух корней, если мнимые */ double discriminant (double a, double b, double c) { return b * b – 4 * a * c; } (boolean, double, double) squareRoots (double a, double b, double c) { final double discr = discriminant(a, b, c); // Значение дискриминанта final double complexFlag = discr < 0; // Определяем, вещественные или мнимые корни (complexFlag, (complexFlag ? ((-b) / (2*a), sqrt(-discr) / (2*a)) : ((-b + sqrt(discr)) / (2*a), (-b – sqrt(discr)) / (2*a)) ); }
  • 5. 5 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Особенности этой программы Вместо переменных и присваиваний используются константы Составные значения легко описываются... ...и создаются Широко используются условные выражения Константы получают динамически вычисляемые значения Тело функции представляет собой суперпозицию применений функций для описания функциональной зависимости результата от входных данных Результаты не зависят от порядка вычислений (возможны параллельные вычисления) double discriminant (double a, double b, double c) { return b * b – 4 * a * c; } (boolean, double, double) squareRoots (double a, double b, double c) { final double discr = discriminant(a, b, c); // Значение дискриминанта final double complexFlag = discr < 0; // Определяем, вещественные или мнимые корни (complexFlag, (complexFlag ? ((-b) / (2*a), sqrt(-discr) / (2*a)) : ((-b + sqrt(discr)) / (2*a), (-b – sqrt(discr)) / (2*a)) ); }
  • 6. 6 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Функциональное представление множеств boolean intSet (int); // описание функционального типа данных boolean emptySet (int n) { return false; } // пустое множество boolean oddSet (int n) { return n % 2 == 1; } // множество нечетных чисел Несколько полезных операций над множествами intSet addElement (intSet s; int newElem) { boolean newSet (int n) { return s(n) || (n == newElem); } return newSet; } intSet buildInterval (int min, int max) { boolean newSet (int n) { return (n >= min) && (n <= max); } return newSet; } intSet difference (intSet s1, intSet s2) { boolean newSet (int n) { return s1(n) && ! s2(n); } return newSet; } Будут ли работать эти операции?
  • 7. 7 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Попробуем вычислить выражение difference (oddSet, addElement (emptySet, 3)) (7) { Принадлежит ли 7 множеству [odds] [3] } addElement s = emptySet newElem = 3 boolean emptySet (int n) { return false; } intSet addElement (intSet s, int newElem) { boolean newSet (int n) { return s(n) || (n == newElem); } return newSet; } boolean oddSet (int n) { return n % 2 == 1; } intSet difference (intSet s1, intSet s2) { boolean newSet (int n) { return s1(n) && ! s2(n); } return newSet; } Стек вычислений newSet s2 = addElement.newSet s1 = oddSet difference newSet
  • 8. 8 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Функциональное представление множеств в языке Java В языке Java все же можно построить правильную программу для работы с функциональным представлением множеств: abstract class IntSet { abstract boolean has(int elem); public static IntSet addElement(final IntSet s, final int n) { return new IntSet() { public boolean has(int elem) { return elem == n || s.has(elem); } }; } public static IntSet buildInterval(final int n, final int m) { return new IntSet() { public boolean has(int elem) { return elem >= n && elem <= m; } }; } public static IntSet difference(final IntSet s1, final IntSet s2) { return new IntSet() { public boolean has(int elem) { return s1.has(elem) && ! s2.has(elem); } }; } public static void main(String[] args) { IntSet emptySet = new IntSet() { public boolean has(int e) { return false; }}; IntSet oddSet = new IntSet() { public boolean has(int e) { return e % 2 == 1; }}; System.out.println(difference(oddSet, addElement(emptySet, 3)).has(7)); } }
  • 9. 9 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Подведение итогов  Императивные языки служат для описания процессов; функциональные – для описания функций, вычисляющих результат по исходным данным.  На традиционных языках можно писать в функциональном стиле, однако средств работы с функциями в традиционных языках недостаточно или они неудобны.  Традиционные способы реализации языков программирования плохо подходят для программ, написанных в функциональном стиле.  Традиционные языки не могут обеспечить удобных средств для распараллеливания вычислений: последовательное выполнение команд – узкое место традиционной архитектуры компьютеров («фон-Неймановское горлышко»).  Для функционального программирования требуются специализированные языки
  • 10. 10 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Литература Основная Дополнительная 1. А. Филд, П. Харрисон. Функциональное программирование. М.: Мир, 1993. 2. П. Хендерсон. Функциональное программирование. Применение и реализация. М.: Мир, 1983. 3. А.А.Кубенский. Функциональное программирование. ИТМО, 2010. 1. Пол Хьюдак, Джон Петерсон, Джозеф Фасел. Мягкое введение в Haskell. RSDN Magazin, 2006 № 4 и 2007 № 1 (http://rsdn.ru/article/haskell/haskell_part1.xml, http://rsdn.ru/article/haskell/haskell_part2.xml) 2. Р. В. Душкин Функциональное программирование на языке Haskell (+ CD-ROM) Издательство: ДМК Пресс, 2007 г., Мягкая обложка, 608 стр. 3. Н.А.Роганова. Функциональное программирование. Учебник для вузов, 2002. 4. Graham Hutton. Programming in Haskell. 2007 г., Мягкая обложка, 184 стр. 5. Bryan O'Sullivan, John Goerzen, Donald Stewart. Real World Haskell: Code You Can Believe In. Издательство: O'Reilly Media, 2008 г., Мягкая обложка, 710 стр.
  • 11. 11 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. 1.2. Введение в язык Haskell История языка Haskell  1960: John McCarthy, LISP – первый функциональный язык программирования  1978: John Backus, FP – система комбинаторного программирования  конец 1970-х: Edinburgh univ., ML – meta-language  1985-1986: David Turner, Miranda – функциональный язык с «ленивыми» вычислениями  начало 1930-х: Church, формализация функций в λ-исчислении  1990: Ericsson, Erlang – «коммерческий» функциональный язык  1988: Paul Hudak, Haskell – первая версия языка Haskell  1999: Haskell group, Haskell’98 – «стандартная» версия языка Haskell Haskell – чисто функциональный язык программирования, названный в честь Хаскелла Карри (Haskell B. Curry – 1900-1982), известного, главным образом, благодаря работам в области математической логики и комбинаторной логики в конце 1950-х – начале 1960-х годов http://haskell.org/onlinereport/index.html - пересмотренное сообщение о языке Haskell’98 http://haskell.org/tutorial - «Нежное» введение в Haskell
  • 12. 12 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Типы данных и базовые конструкции языка Haskell Элементарные типы данных  Integer, Int – целые значения (25, -17, 111222333444555666777888)  Float, Double – вещественные значения (3.14, -2.718281828459045)  Char – символьные значения ('A', '*', '3')  Bool – логические значения (True, False) Идентификаторы: fact, fAcToRiAl, fact_1, fact'' Знаки операций: +, -, *, <, == Идентификаторы применяются для обозначения констант – значений разных типов (простых, составных, функций) и типов. Любому идентификатору можно сопоставить тип и значение: school :: Integer school = 239 piHalf :: Double piHalf = 3.1415926536 / 2
  • 13. 13 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Кортежи и функции Значения могут объединяться в более сложные с помощью кортежирования. Например: pair :: (Double, Double) pair = (2.7, 3.14) attributes :: (Char, (Int, Int, Int), Bool) attributes = ('M', (17, 4, 1955), True) Тип функции определяется типами аргументов и результата, например: sin :: Double -> Double -- аргумент и результат типа Double plusInt :: Int -> Int -> Int -- два аргумента типа Int, результат Int divMod :: (Int, Int) -> (Int, Int) -- аргумент и результат - кортежи Выражения составляются из констант применением операций и функций, например: result = sin (3.1416 / 4) - 2.5 c10 = 3 + plusInt 3 4 pair = divMod (1458, plusInt 176 192) Операции и функции отличаются только формой записи. Следующие выражения эквивалентны: 3 + 8 и (+) 3 8 27 `div` 4 и div 27 4 7 `plusInt` 11 и plusInt 7 11
  • 14. 14 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Определение функций с помощью уравнений Уравнения задают правила, по которым происходит вычисление функции, то есть каким образом результат получается из аргументов функции, например: plusInt :: Int -> Int -> Int plusInt a b = a + b divMod :: (Int, Int) -> (Int, Int) divMod (a, b) = (a `div` b, a `mod` b) Уравнения могут содержать условные выражения и рекурсивные обращения, например: factorial :: Integer -> Integer factorial n = if n == 0 then 1 else n * (factorial (n-1)) sum :: Integer -> Integer sum n = n + if n == 0 then 0 else sum (n-1) factorial1 :: Integer -> Integer factorial1 n | n == 0 = 1 | n > 0 = n * (factorial1 (n-1)) factorial2 :: Integer -> Integer factorial2 0 = 1 factorial2 n = n * (factorial2 (n-1)) Уравнений для одной функции может быть несколько, тогда аргументы последовательно сопоставляются с образцами:
  • 15. 15 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Подготовка и запуск программ factorial :: Integer -> Integer factorial n | n == 0 = 1 | n > 0 = n * (factorial (n-1)) В лекциях всюду используется «краткий» синтаксис, при котором каждое новое определение начинается с новой строки. Этот синтаксис очень чувствителен к расположению строк. Каждое новое «предложение» должно начинаться ровно в той же позиции, что и предыдущее. Если требуется разместить «предложение» на нескольких строках, то «продолжения» должны начинаться с отступом от позиции предыдущей строки - ошибка factorial :: Integer -> Integer factorial n | n == 0 = 1 | n > 0 = n * (factorial (n-1)) - ошибка Заметьте, что второе уравнение, в котором опущены имя функции и образец, синтаксически является продолжением первого уравнения. factorial :: Integer -> Integer factorial n | n == 0 = 1 | n > 0 = n * factorial (n-1)) - нет ошибки
  • 16. 16 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Подготовка и запуск программ «Полный» синтаксис подразумевает, что последовательность «предложений» заключается в фигурные скобки, а отдельные предложения отделяются друг от друга точками с запятой. В случае использования «полного» синтаксиса соблюдать отступы не обязательно. { factorial :: Integer -> Integer; factorial n | n == 0 = 1 | n > 0 = n * (factorial (n-1)) } - нет ошибки В программе можно смешивать полный и краткий синтаксис. Анализатор переключается между ними по следующим правилам: • анализ начинается в режиме полного синтаксиса; • если там, где нужна открывающая фигурная скобка, ее нет, то она автоматически вставляется, а анализатор переходит в режим краткого синтаксиса; • если в режиме краткого синтаксиса очередная строка начинается с той же позиции, что и начало всего предложения, то перед ней автоматически вставляется точка с запятой; • если очередная строка начинается с отступом влево от начала текущего предложения, то вставляется закрывающая фигурная скобка; • если очередная строка начинается с отступом вправо, то это – продолжение предыдущей строки (ничего не вставляется)
  • 17. 17 Исполнение программ с помощью текстовой подстановки factorial :: Integer -> Integer factorial n | n == 0 = 1 | n > 0 = n * (factorial (n-1)) factorial 3 3 * (factorial (3-1)) 3 * (factorial 2) 3 * (2 * (factorial (2-1))) 3 * (2 * (factorial 1)) 3 * (2 * (1 * (factorial (1-1)))) 3 * (2 * (1 * (factorial 0))) 3 * (2 * (1 * 1)) 6 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.
  • 18. 18 Несколько определений простых арифметических функций Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. -- Вычисление наибольшего общего делителя двух натуральных чисел gcd :: Integer -> Integer -> Integer gcd m n | m < n = gcd n m | n < 0 = error "gcd: Wrong argument" gcd m 0 = m gcd m n = gcd n (m `mod` n) -- Проверка заданного натурального числа на простоту prime :: Integer -> Bool prime' :: Integer -> Integer -> Bool prime p | p <= 0 = error "prime: Non-positive argument" | otherwise = prime' 2 p prime' d p | d * d > p = True | p `mod` d == 0 = False | otherwise = prime' (d+1) p
  • 19. 19 Немного о явных и неявных преобразованиях типов Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования. Язык Haskell – строго типизированный. Это означает, что во время компиляции тип любого выражения известен и контролируется. Тем не менее, многие функции и операции допускают в качестве аргументов (операндов) значения разных типов. 2 + 5 – сложение целых; 2.5 + 3.5 – сложение вещественных; 2 + 3.5 – сложение вещественных (первый операнд перед операцией преобразуется); n + 3.5 where n = 2 – сложение вещественных (тип первого операнда «выводится» как вещественное); fromIntegral n + 3.5 where { n :: Int; n = 2 } – сложение вещественных (тип первого операнда явно преобразован); a + b where { a :: Int; a = 2; b :: Integer; b = 12 } – ошибка (операнды имеют разные типы); n + 3.5 where { n :: Int; n = 2 } – ошибка (тип первого операнда явно указан как целый); a + fromIntegral b where { a :: Int; a = 2; b :: Integer; b = 12 } – сложение коротких целых; Некоторые функции преобразования типов: • fromIntegral, fromRational, fromEnum, • truncate, round, ceiling, floor