
III_201_FP_2013c.ppt
- Количество слайдов: 29
Парадигма функціонального програмування. Знайомство з мовою Haskell 2012 Парадигма FP
Функціональне програмування. Вступ (1/2) Повернення до чистих функцій. – Машинні бібліотеки функцій. – Algol-60: функції з побічними ефектами (червоність). Чистота: обчислення з одними аргументами завжди дає один і той самий результат! • g h f • • • Заміна виразу на результат обчислення виразу. Спрощене тестування. Природні підходи до розпаралелювання. Спрощена інтеграція (інтеграція – один з найбільших ризиків в інженерії ПС). Парадигма FP 2
Функціональне програмування. Вступ • • (2/2) Можна обмежитись одноаргументними функціями, спираючись на каррінг функцій. Формалізація семантики функціональних програм фактично спряжена з уточненням аплікації (застосуванні функції до аргументу). Хоч останнє, як виявляється, не таке вже й просте, тим не менше теоретичні засади давно відомі. Це – лямбда-числення. Лямбда-числення, лише кілька штрихів: – чисте лямбда-числення – це числення анонімних функцій; – бета-редукція як основа трактування аплікації (засади операційної семантики); – можливі різні стратегії використання бета-редукцій, зокрема, є стратегія, спряжена із так званими лінивими обчисленнями, є стратегія, спряжена із так званими енергійними обчисленнями; – застосування теореми про нерухому точку (теореми Чорча. Россера) для функцій із рекурсивними визначеннями. Парадигма FP 3
Haskell де-факто є стандартом мов функціонального програмування. На Haskell реалізовано багато складних проектів. Ось деякий їх перелік із статті за адресою http: //www. ibm. com/developerworks/ru/library/ l-haskell/? S_TACT=105 AGX 99&S_CMP=GR 01 – – – – – Компілятори й інші засоби розробки. Розподілена система керування версіями Darcs. Віконний менеджер xmonad. Сервер Web-додатків HApp. S. Інтерпретатор/компілятор Pugs для мови Perl 6. Операційна система House. Мова опису апаратних засобів Lava. Система обробки натуральної мови LOLITA. Системи доведення теорем Equinox / Paradox і Agda. Парадигма FP 4
Haskell. Типи даних Елементарні типи даних: – Integer (без формальних обмежень!), Int; Haskell – строго типізована мова. – Float, Double; Типи даних програми можна визначити – Char - ‘H’, ‘a’, …; статично (з тексту програми), не потребуючи – Bool - True, False. обов’язкового виконання програми Механізм виведення типів Засоби конструювання складених значень-констант і типів: – списки; (Однозв'язні) списки та (незмінні за – кортежі; розміром) кортежі – є вбудованими складеними типами – функції. (Функції також є значеннями так званого першого класу – вони можуть бути як аргументами, так і результатами обчислення інших функцій. ) Використовується при каррінгу Парадигма FP 5
Haskell. Типи даних. Прилади Як дізнатись про тип? : type. . . Тип для рядків Парадигма FP 6
Синоніми типів type String = [Char] type Pair. Int = (Int, Int) type Pair = (a, b) type Vector = (Double, Double) type Name = String Синоніми типів задають нові імена для існуючих типів (нові типи не визначаються!). Вони можуть підвищувати читабельність програми за рахунок більшої мнемонічними. Парадигма FP 7
Haskell. Типи даних. Поліморфні типи Як це розуміти? ? Тип [a] є прикладом поліморфного тип. З ним пов’язується сімейство будь-яких типів списків з (однотипними!) елементами з a. (Мова ведеться про сімейство — оскільки тип a не уточнюється, тобто вважається присутнім квантор a. При цьому a природно розглядати як змінну типу. Загалом, поліморфний тип – це тип, що задається виразом, у якому всі змінні типу розглядаються як зв'язані кванторами узагальнення. Ще один приклад. Парадигма FP 8
Визначення функцій за допомогою рівнянь. Типи функції. Поліморфні функції Приклад визначення функцій за допомогою одного рівняння: : set prompt > Зміна підказки swap (x, y) = (y, x) Функціональний тип! Swap є прикладом, відповідно, поліморфної функції. Вона може Маємо єдину реалізацію для різних типів параметрів бути застосована до будь яких пар (двоелементних кортежів). Параметричний поліморфізм (чистий) Парадигма FP 9
Параметричний поліморфізм (1/3) • Підвищується виразність мови. • Підтримуване у Haskell виведення типів знімає тягар типізації з програміста. – Основний тип виразу чи функції – це найменш загальний тип, що, грубо кажучи, містить усі можливі “екземпляри” виразу чи функції. Приклад 1. (Одне рівняння). swap(x, y) = (y, x) (t 1, t 2) -> (t 3, t 4) (t 1, t 2) -> t 3 t 1 -> t 2 Найменш загальний тип – тип функції swap Більш загальні типи Парадигма FP 10
Параметричний поліморфізм (2/3) Приклад 2. (Два рівняння). head 1 (x: _) = x head 1 [] = error "List empty" Зіставлення зі зразком (pattern matching) Та ж уніфікація! Найменш загальний тип [t 1] -> t 2 t 1 -> t 2 Більш загальні типи, ніж тип [t] -> t Парадигма FP 11
Параметричний поліморфізм (2/2) • Є ще один варіант поліморфізму – спеціальний (ad hoc) поліморфізм, більш відомий як перевантаження (overloading). – Розглянемо лише один приклад для розуміння проблеми. Оператор порівняння або рівності (==) зазвичай використовується із багатьма типами. Але, по-перше, не з усіма (оскільки, наприклад, порівняння функцій спряжене з алгоритмічно нерозв'язною проблемою) і, по-друге, порівняння, скажімо, двох списків чи дерев істотно відрізняється від порівняння двох чисел (саме тому природним є використання перевантаження оператора (==) для таких різноманітних порівнянь). – Використання спеціального поліморфізму (перевантаження) у мові Haskell спряжене із залученням так званих класів типів. Приклад. invers x = -x Парадигма FP Клас типів 12
До визначення функцій. Зіставлення зі зразком • Визначення функцій за допомогою рівнянь. Вже зустрічались із прикладами. . . Зіставлення зі зразком (pattern matching) Кілька рівнянь Та ж уніфікація! “: ” – інфіксний оператор, що додає перший аргумент як “голову” у початок списку, який визначається другим аргументом. “: ” – правоасоціативний оператор, тому вираз 1: (2: (3: [])) можна записувати як 1: 2: 3: []. Скорочена форма для списків: замість 1: 2: 3: [] можна вживати [1, 2, 3]. Приклад 1. head 1 (x: _) head 1 [] = = x error "List empty" Wildcards (підстановкові символи) Приклад 2. tail (_: xs) = xs tail [] = error " List empty " Парадигма FP 13
До визначення функцій. Рекурсивні функції Приклад 1. last : : [a] -> a [x] = x (_: xs) = last xs [] = error "List empty" Приклад 2. reverse 0 y = reverse 1 y [] Відомий прийом – використання допоміжної більш загальної функції. reverse 1 [] y = y reverse 1 (x: xs) y = reverse 1 xs (x: y) reverse 1 [1, 2, 3] y 3: (2: (1: y)) Зверніть увагу на форму використання двох аргументів у reverse 1 та особливості їх нотації (немає дужок, коми між аргументами). Парадигма FP 14
До визначення функцій. Каррінг (1/2) reverse 1 [] y = y reverse 1 (x: xs) y = reverse 1 xs (x: y) reverse 1 [1, 2, 3] y 3: (2: (1: y)) Вираз (функціонального) типу ? [a] -> ([a] -> [a]) З огляду на правоасоціативність “->” у мові Haskell Реальний тип reverse 1. Тобто маємо унарну функцію, яка відображає списки (типу [a]) у функції (типу [a]->[a] ). “Часткове” обчислення Пригадаємо: • Можна обмежитись одноаргументними функціями, спираючись на каррінг функцій. Такий підхід до тлумачення функцій саме і популяризував Haskell Curry. Усі функції у мові Haskell розглядаються як каррінгові функції Парадигма FP 15
До визначення функцій. Каррінг (2/2) reverse 1 [] y = y reverse 1 (x: xs) y = reverse 1 xs (x: y) reverse 1 [1, 2, 3] y 3: (2: (1: y)) [a] -> ([a] -> [a]) Реальний тип reverse 1 Переконаємось у каррінговості reverse 1, зокрема, спробуємо здійснити часткові обчислення: Зверніть увагу на круглі дужки Можна визначити нову функцію reverse 1_1_2_3 на основі часткового обчислення: reverse 1_1_2_3 = reverse 1 [1, 2, 3] Парадигма FP 16
Каррінг. Ще кілька простих прикладів 1) plus x y : : = Integer -> Integer x + y plus 1 = plus 1 2) plus_ x y = x+y (Тип функції виводиться у Haskell!) Парадигма FP 17
Функції та типи. Ще кілька прикладів fst (x, y) : : (a, b) -> a = x snd (x, y) : : (a, b) -> b = y type Vector = (Double, Double) add. Vector : : Vector -> Vector add. Vector x y = (fst x + fst y, snd x + snd y) Парадигма FP 18
Функції як аргументи. Кілька прикладів map 1 f [] map 1 f (x: xs) : : (a->b) -> [a] -> [b] = [] = f x : map f xs curry : : ((a, b) -> c) -> a -> b -> c curry f x y = f (x, y) uncurry : : (a -> b -> c) -> ((a, b) -> c) uncurry f p = f (fst p) (snd p) plus_pair = uncurry plus Парадигма FP Замість каррінгових функцій від двох аргументів іноді простіше мати справу з функцією над кортежною парою або ж, навпаки, замість одноаргументної функції від кортежної пари – мати справу із каррінговою функцією від двох аргументів 19
Haskell-програми. Приклади (1/3) list comprehension: [ f x | x <- xs ] Алгоритм швидкого сортування: quicksort [] = quicksort (x: xs) = ++ ++ [] quicksort [y | y <- xs, y
Haskell-програми. Приклади (2/3) get. Divisors num | num < 1 | otherwise is. Prime num | num <= 1 | otherwise all. Prime. Numbers = [] = [x | x <- [1. . num], num `mod` x == 0 ] = False = get. Divisors num == [1, num] = filter is. Prime [1. . ] all. Prime. Numbers 1000000 = [y | y <- all. Prime. Numbers, y>1000000] main = take 1 all. Prime. Numbers 1000000 Парадигма FP 21
Haskell-програми. Приклади (3/3) zip. F : : (a -> b -> c) -> [a] -> [b] -> [c] _ [] [] = [] f (x 1: s 1) (x 2: s 2) = (f x 1 x 2) : zip. F f s 1 s 2 fib = 1 : zip. F (+) fib (0 : fib) goal = fib where fib 0 = 0: fib 1 = zip. F (+) fib 0 fib = 1: fib 1 zip (x: xs) (y: ys) = (x, y) : zip xs ys = [] fib = 1 : [ a+b | (a, b) <- zip fib (tail fib) ] Парадигма FP 22
Додаток Парадигма FP
http: //www. haskell. org Парадигма FP 24
http: //www. haskell. org/platform/ Парадигма FP 25
http: //www. haskell. org/platform/windows. html Парадигма FP 26
GHC home page (http: //www. haskell. org/ghc/) Парадигма FP 27
Language and library specification (http: //www. haskell. org/haskellwiki/Definition) Парадигма FP 28
The Glasgow Haskell Compiler Два варіанти “запитів“: – вирази; – команди (інтерпретатора). (Команди починаються символом “: ”). Приклади команд (назви команд можна скорочувати до одного символа): : quit; : type; : set - для встановлення опцій інтерпретатора. Наприклад, : set +t (для виведення типу кожного обчисленого результату); : set prompt > (змінюється вигляд запрошення). : ? - виводиться список можливих команд; : load. . . ; : reload; : edit. Парадигма FP 29