slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Функциональное программирование PowerPoint Presentation
Download Presentation
Функциональное программирование

Loading in 2 Seconds...

play fullscreen
1 / 48

Функциональное программирование - PowerPoint PPT Presentation


  • 225 Views
  • Uploaded on

Функциональное программирование. Функциональное программирование. Симуни Михаил Лазаревич msimuni.wikidot.com/fp группа ВКонтакте “ Функциональное программирование (мат-мех 14 ) ” simuni@mail.ru. Что надо будет для зачета?. Набрать >= 20 баллов Контрольная в середине курса

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Функциональное программирование' - bevis-hodges


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1

Функциональное программирование

slide2
Функциональное программирование

Симуни Михаил Лазаревич

msimuni.wikidot.com/fp

группа ВКонтакте “Функциональное программирование (мат-мех 14)”

simuni@mail.ru

slide3
Что надо будет для зачета?
  • Набрать >= 20 баллов
  • Контрольная в середине курса
  • Зачет: задачи + теор.вопросы
  • Больше баллов – льготы на зачете

30 – минус 1 задача40 – минус 2 задачи50 – минус 3 задачии т.д.

slide4
Откуда берутся баллы

Задачи на дом (примерно по 4 задачи на занятии)

И еще будут дополнительные задачи посложнее

MOOC ?

Scala – Martin Odersky Functional programming - Erick Mejer

если кто-то прослушает какой-нибудь курс и покажет сертификат – 30 баллов

Или если кто-то слушал ФП в Computer Science Center и может это продемонстрировать – тоже 30 баллов

4

slide5
Про задачи

Как сдавать задачи:

Система тестированияhttp://ms8255.ru/fp

Или можно присылать по почте, или приносить на листке

Правила про задачи:

Надо сдавать не позже начала пары

Можно писать не (совсем) правильно

Нельзя присылать очень похожие решения…

5

slide6
На чем писать?
  • Я пишу на Haskell
  • Если есть желающие, можно F#, LISP (Clojure, Racket и т.д.), ML (OCaml), Scala, Erlangи т.д.

(почти для всех задач)

  • А м.б. и Питон, Ruby и т.д.
  • Компиляторы – Haskell Platform, WinHugs, FP Haskell Center
  • На сайте документы про то, как начать работать с WinHugsи Haskell Platform
slide7
Литература
  • Литература
    • См. ссылки на сайте
    • Роганова Н.А. «Функциональное программирование» – основы, очень просто
    • «Изучай Хаскел ради добра»
    • Г.Макеев «Основы функционального программирования на языке Haskell»
slide9
Кто придумал ФП?

Alonzo Chirch

  • Примерно 1932 г.

до первого компьютера!

(1941, К.Цузе)

Что такое алгоритм? Каким минимальным набором средств, можно описать любой алгоритм?

Ответы:

  • Тьюринг: Машина Тьюринга
  • Черч:Лямбда-исчисление: Функции!
slide10
Лисп

John McCarthy

  • 1958 г. LISPЯзык высокого уровня #2!

(После Фортрана)

  • Маленький и простой
  • Не используется GOTO и т.д.
  • Сборка мусора
  • Программы можно использовать, как данные
haskell
Haskell и потом
  • Scheme, ML, OCAML …
  • 1990 – Haskell
  • C# 3.0
  • F#
  • C++11
  • Java 8
  • Erlang
  • Scala
  • Python, Ruby и т.д.
slide13
Что такое ФП?

Wikipedia:“programming paradigm, that treats computation as the evaluation of mathematical functions and avoids state and mutable data.”

  • Т.е. мы себя ограничиваем
    • Не используем оператор присваивания
      • Все переменные const
    • Не используем for и т.д.
  • А.П.Ершов: Примерно как играть в волейбол с одной привязанной рукой
  • Зачем?
    • Меньше ошибок
    • Проще оптимизировать
    • Проще выполнять параллельно
    • И т.д.

Убедительно?

  • John Hughes «Why Functional Programming Matters»«Если бы исключение оператора присваивания принесло такие огромные выгоды, то программисты на Фортране сделали бы это лет двадцать назад».
slide14
Функции высшего порядка
  • Функция, параметр которой – тоже функция. Например:
    • integral(0, 1, sin)
    • draw(0, 1, cos)
    • forall(list, print);
  • Можно зайти очень далеко (и мы постараемся):
    • Функции, как результат функции
    • Сложные случаи (функция, которая возвращает функцию, которая возвращает функцию и т.д.)
  • Например, одна из функций, которую придумал Черч:λn.λf.λx. n (λg.λh. h (g f)) (λu. x) (λu. u)
slide15
Ленивые вычисления, бесконечные списки
  • x = sin(y);

идея: может быть, тут не вычислять ничего…

cout << x;

… ивот только тут вычислить sin

  • И тоже постараемся далеко зайти…
  • Бесконечные списки

Как найти n-ное число Фибоначчи?

    • Описать бесконечный список, в котором каждый элемент равен сумме двух предыдущих
    • Взять в этомсписке n-ный элемент
slide16
Система типов

Вывод типов

  • C#:var x = Math.Sin(1);
    • Не надо писать тип x – компилятор и сам может догадаться
  • И, опять же, попробуем далеко зайти)
    • Вообще не пишем типы (ну, почти совсем…). Но они есть – компилятор выводит их сам.

Полиморфизм

  • То, что в С++ хотели ввести под именем concept (но не очень получилось)
slide17
Фокусы
  • continuations
    • «вызвать функцию, апотом …»
  • Монады
    • Один из примеров: Выполняем последовательность действий до первой ошибки
  • М.б. еще что-то (lens, arrows)??
slide18
Теория
  • Лямбда исчисление
  • Изоморфизм Карри-Ховарда
  • М.б. еще что-то?? (free theorems?)
slide19
Это все действительно полезно знать?
  • Будете ли вы писать на Хаскеле?
    • Скорее всего, нет 
  • Будете ли вы использовать приемы ФП в обычных языках?
    • Скорее всего, да
  • М.б. полезные приемы
    • Просто как пример, Map/Reduce
  • Развивает сообразительность…
slide21
Лексика
  • Комментарии

-- это комментарий

{-- Аэто

многострочный комментарий --}

  • Имена
    • Первая буква имеет значение
      • x, sin – переменные, функции
      • Integer, True- имена типов, константы
    • Можно использовать кавычки
      • abc’
slide22
Числа

Как обычно: 563.1415926

3.0e9

  • М.б. бесконечнозначные

2^100 2^1000

Операции как обычно:

  • + - * /
  • Для деления нацело с остатком функции div, mod
  • ^ - возведение в степень

2^1000 =

1071508607186267320948425049060001810561404811705533607443750388370351051124936122493198378815695858127594672917553146825187145285692314043598457757469857480394567774824230985421074605062371141877954182153046474983581941 267398767559165543946077062914571196477686542167660429831652624386837205668069376

slide23
Логические значения
  • Сравнение
    • Не равно: /=
    • Остальное как обычно: < <= > >= ==
  • True, False
  • && || not

Пример:x*y < 0 && (y*y + x*x < 1)

slide24
Функции

Не совсем обычно!

  • Не пишутся ни запятые, ни скобкиsin xmod k 10 + div k 10
  • Приоритет: сначала функции, потом операторы

sin x*x– это(sin x) * x

Совет:Непонятная ошибка  проверьте, правильно ли расставлены скобки

  • f g x – это (f g) x

Т.е. скобки группируются слева направо.

    • sin sin 1 – это (sin sin) 1 (ошибка)
    • А когда это удобно? Позже обсудим…
slide25
Как определить свою функцию
  • Самый простой пример:

sqr x = x*x

Потом:

sqr 5

  • Пример простой рекурсивной функции

(Конечно же, это факториал:)

fact 1 = 1

fact n = fact (n-1) * n

  • Порядок важен!

fact n = fact (n-1) * n

fact 1 = 1

// Досюда не дойдет:(

  • Одно ограничение, на первый взгляд непонятное:

f n n = … // Так нельзя!

    • Переменная слева от = не может встречаться 2 раза (называется: линейность)
slide26
Условный оператор.Где начинается следующее правило?
  • if условие then выражение else выражение

abs x = if x > 0

then x

else –x

f x = x + if x > 0 then x else 0

  • Откуда компилятор знает, где начинается следующее правило?
    • С первой позиции в строке новое правило
    • Строка начинается с пробела продолжение правила
slide27
Операторы
  • Можно определять свои операторы

i @@ j = i*i + j*j

  • Пример вызова

5 @@ 7

    • Может использоваться любая последовательность символов (кроме зарезервированных типа -> и ::)
  • Обычные функции можно использовать, как инфиксный оператор
    • Надо взять в обратные кавычки (`)

i `mod` 100

slide28

Хвостовая рекурсияНакапливающие параметры

slide29
Как вычисляется факториал

fact 1 = 1

fact n = fact (n-1) * n

fact 5 = fact 4 * 5

fact 4 = fact 3 * 4

fact 3 = fact 2 * 3

fact 2 = fact 1 * 2

fact 1 = 1

  • Для fact 1000000 на стеке будет 1000000 вызовов

120

24

6

2

1

slide30
Еще вариант факториала
  • Давайте сразу перемножать во время рекурсии

fact n = fact’ n 1

fact' 1 p = p

fact' np = fact’ (n-1) (n*p)

fact' 5 1 = fact’ 4 (5*1)

fact'4 5 = fact’ 3 (4*5)

fact’ 3 20 = fact’ 2 (3*20)

fact’ 2 60 = fact’ 1 (2*60)

fact’ 1 120 =120

fact n = fact’ n 1

fact' n p = fact’ (n-1) n*p

fact' 1 p = p

  • Две ошибки 

5 1

4 5

3 20

2 60

1 120

slide31
Хвостовая рекурсия
  • Если вызов функции – это последнее, что происходит при вычислении правило, то он называется хвостовым вызовом (tail call).
  • Если в некоторой функции все рекурсивные вызовы – хвостовые, то говорят, что в этой функции используется хвостовая рекурсия (tail recursion)
  • Студент X: пример хвостовой рекурсии:fact n = n * fact (n-1)
    • Нет!
  • Зачем нужна хвостовая рекурсия?
    • Можно реализовать более эффективно (и во многих языках так и реализовано)
    • Но не в Haskell…
    • Иногда просто удобнее писать (накапливающие параметры).
slide32
Накапливающие параметры

fact' 1 p = p

fact' np = fact’ (n-1) (n*p)

  • Функция использует p, чтобы передавать в рекурсивный вызов информацию о частично вычисленном значении.
  • Называется накапливающие параметры (accumulating parameters)

Еще пример:

  • sumprod n = 1 + 2 + … + n / 1*2*3*…*n

sumprod n = sumprod’ n 0 1

sumprod' 0 s p = s / p

sumprod' n s p = sumprod’ (n-1) (s+n) (p*n)

slide34
Списки
  • Основной тип данных
    • (и почти во всех функциональных языках)
  • Примеры:

[1, 2, 3]

[3.5, 2.123, 98.14]

[True, False]

  • Элементы д.б. одного типа!

[1, True, 2] -- Ошибка!

slide35
Как создавать списки Оператор :
  • Оператор :
    • Приписать элемент в начало

1 : [2,3]  [1,2,3]

  • Пример:

f 0 = []

f n = n : f (n-1)

    • Список чисел от n до 1
  • Кстати:[a..b] – числа от a до b с шагом 1
  • На самом деле, [1,2,3] – это просто сокращение!
    • [1, 2, 3] – сокращение для 1:2:3:[]
    • Так и хранится:

:

/ \

1 :

/ \

2 :

/ \

3 []

slide36
Как обрабатывать списки – способ 1
  • head – первый элемент списка
  • tail – все,кроме первого элемента («хвост»)

head [1,2,3]  1

tail [1,2,3]  [2,3]

  • Пример: сумма элементов списка

sum [] = 0

sum xs = head xs + sum(tail xs)

Замечания:

  • Типичные имена для списков в Haskel: xs, ysи т.д.
  • sum – на самом деле, есть такая стандартная функция
slide37
ШаблоныКак обрабатывать списки – способ 2

sum [] = 0

sum (x:xs) = x + sum xs

  • Слева от = м.б. выражение с переменными – шаблон (pattern)
  • Шаблоны м.б. довольно сложным
    • Примеры:

f [x, y, z]

f [1, y, 2]

f (x:y:xs)

f (x:1:xs)

Замечания:

  • sum (x:xs) – скобки нужны!
  • Еще раз, правило линейности:
    • f [x, y, x] -- ошибка!
slide38
Еще пример
  • product – произведение чисел списка (стандартная функция)

product [] = 1

product (x:xs) = x * product xs

  • Снова факториал

fact n = product [1..n]

    • Это стиль Haskell!
  • Fritz RuehThe Evolution of a Haskell Programmerhttp://www.willamette.edu/~fruehr/haskell/evolution.html
slide39
++
  • Еще одна стандартная функция
    • Конкатенация - оператор ++

[1,2] ++ [3,4]  [1,2,3,4]

[] ++ ys = ys

(x:xs) ++ ys =

x : (xs ++ ys)

  • Кстати: как приписывать в конец списка
    • xs : x
      • Нет!: приписывает только в начало!
    • xs ++x
      • Нет!++ работает только со списками!
    • xs ++ [x]
      • OK
      • Но O(n) – медленно!
slide41
Пример: map
  • Взять синус от всех элементов списка

sinAll [] = []

sinAll (x:xs) = sin x : sinAll xs

  • Взять косинус от всех элементов списка

cosAll [] = []

cosAll (x:xs) = cos x : cosAll xs

  • Возвести все элементы списка в квадрат
    • :( Надо что-то делать!
  • map

map f [] = []

map f (x:xs) = f x : map f xs

  • Примеры вызова

map sin [1,2,3]

 [sin 1, sin 2, sin 3]

map sqr [1,2,3]

 [1,4,9]

  • Функция высшего порядка!
slide42
Лямбда-выражения
  • Почему в обычных языках (Паскаль, C) этим мало пользуются?
  • Еще задача: К каждому числу в списке приписать 7 справа.

f x = 10 * x + 7

map f xs

      • Надо описывать вспомогательные функции – лень 
      • Надо придумывать имена – тоже лень 
  • Лямбда-выражение – функция без имени
    • \i -> 10*x + 7

map (\i -> 10*i+7) xs

  • Синтаксис:

\ параметр1 параметр2 ->выражение

    • \ - то, что осталось от λ
  • Ограничения:
    • М.б. только одно правило (но case)
    • Естественно, не м.б. рекурсивно
trace show
trace, show

import Debug.Trace

… trace строка значение …

  • Возвращает значение
  • Печатает строку
  • Пример:

height Empty = trace "!!!" (-1)

  • show
    • show 66  "66"
    • Не требует import, есть почти для всех обьектов
    • show [1,2,3]  "[1,2,3]"
  • Пример trace + show:

fact i = trace (show i) i *fact (i-1)

slide45
Функции высшего порядка в C#Как описыватьпараметры-функции
  • Как описывать параметры – функции
  • Как задавать значения для параметров-функций
  • Как описывать:

Func<int, int> f

    • Func<тип1, тип2, … ,тип_результата>

Func<int, double, bool>

    • Это сокращение для delegate
  • Специальные случаи:
    • Predicate<int> pred
      • функция с одним параметром и логическим значением
    • Action<int> act

Action<int, double> act1

      • Функция возвращает void
slide46
Как задавать значения для параметров-функций
  • Что можно передавать в функцию с параметром-функцией?
    • Имя статического метода
    • Expression lambdaпараметр => выражение или (параметр, параметр, …) => выражение

i => i*i

(i, j) => i + j

      • Можно указывать типы (но обычно не нужно)

(int i, int j) => i + j

  • Statement lambdaпараметр => блок или (параметр1, параметр, …) =>блок

n => { int p = 0; for(int i=1;i<=n;i++)

p*=i;

return p; }

  • Есть еще возможности (delegate, не статические методы…)
slide47
Пример

static void PrintTable( Func<int, int> f, int n)

{

for (int i = 0; i <= n; i++)

{

Console.WriteLine("{0} {1}", i, f(i));

}

}

static int Cube(int i)

{

return i * i * i;

}

// Примеры вызова:

PrintTable(Cube, 10);

Func<int, int> sqr = i => i * i;

PrintTable(sqr, 10);

PrintTable(i => i*i, 10);

refential transparency
Refential transparency
  • Что такое ‘побочный эффект’?
  • Прозрачность по ссылкам (referential transparency)

… f 5 + … f 5 …

    • Вызовы с одинаковыми параметрами всегда дают одинаковые значения
    • Можно заменить на один вызов (с помощью let, например)

Не очень понятно:

  • А как же случайные числа??
  • А как же ввод/вывод??