Download - Функциональное программирование
![Page 1: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/1.jpg)
Сошников Дмитрий Валерьевич
к.ф.-м.н., доцент[email protected]
Факультет инноваций и высоких технологий
Московский физико-технический институт
![Page 2: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/2.jpg)
Лекция 6
Сопоставление с образцом. Рекурсия. Циклы
![Page 3: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/3.jpg)
3
©20
08 С
ошни
ков
Д.В
.
type document = SSN of int | Passport of string;;type personx = string * int * document;;let vasyax = ("Vasya",14,SSN 1234);;
let (_,_,doc)= vasyax;;
match vasyax with _,_,SSN x -> print_int x| _,_,Passport s -> print_string s;;
let print_doc = function _,_,SSN x -> print_int x| _,_,Passport s -> print_string sin print_doc vasyax;;
![Page 4: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/4.jpg)
4
©20
08 С
ошни
ков
Д.В
.
match expr with pattern1 [when cond1] -> expr1| pattern2 [when cond2] -> expr1| …;;
match D with _ when D>0 -> “Два корня”| _ when D=0 -> “Один корень”| _ -> “Нет корней”;;
match root with Some(t) -> printf “Корень: %d\n” t| None -> printf “Корней нет\n”
![Page 5: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/5.jpg)
5
©20
08 С
ошни
ков
Д.В
.
Конструкции для определения лямбда-выражений:
fun Поддерживает несколько аргументов в
каррированной форме: fun x y -> … Не поддерживает pattern matching
function Поддерживает только один аргумент
(возможно, tuple) Поддерживает pattern matching с
несколькими вариантами описания
![Page 6: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/6.jpg)
6
©20
08 С
ошни
ков
Д.В
.
let rec fact1 = function 1 -> 1| x -> x*fact1(x-1);;
let rec fact2 x = match x with 1 -> 1 | x -> x*fact2(x-1);;
// это уже не pattern matchinglet rec fact3 x = if x = 1 then 1 else x * fact3(x-1);;
![Page 7: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/7.jpg)
7
©20
08 С
ошни
ков
Д.В
.
Определения в F# могут быть рекурсивными, т.е. в рамках «let rec»- определения возможно использовать определяемую функцию
В λ-исчислении напрямую понятия рекурсии нет – мы позднее узнаем, как определяется рекурсия в λ-исчислении
Рекурсия – зачастую единственный способ совершения итеративных действий
![Page 8: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/8.jpg)
8
©20
08 С
ошни
ков
Д.В
.
let rec print_n a b = if a>=b then print_int b else begin print_int a; print_n (a+1) b end;;
print_n 1 10;;
Напечатать числа от a до b
![Page 9: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/9.jpg)
9
©20
08 С
ошни
ков
Д.В
.
Группировка по блокам регулируется отступами
Можно опускать некоторые элементы синтаксиса, например, in в let … in …
#lightlet rec print_n a b = if a>=b then print_int b else print_int a print_n (a+1) b;;print_n 1 10;;
![Page 10: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/10.jpg)
10
©20
08 С
ошни
ков
Д.В
.
print_n – типичная реализация цикла со счетчиком
Необходимо выполнить какое-то действие несколько раз, при этом переменная-счетчик меняется от a до b
Действие можно задать функцией int → unit
Функционал – функция, принимающая или возвращающая функцию
![Page 11: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/11.jpg)
11
©20
08 С
ошни
ков
Д.В
.
В F# (но не в других функц.языках) имеется также встроенная конструкция цикла for:
let rec forl a b f = if a>=b then f b else f a forl (a+1) b f;;
forl 1 10 (fun i -> print_int i);;
for i=1 to 10 do print_int i;;for i in 1..10 do print_int i;;
![Page 12: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/12.jpg)
12
©20
08 С
ошни
ков
Д.В
.
fora a b i f = f(f(…f(i,b),…),a+1,a)let rec fora a b i f = if a>=b then i else f (fora (a+1) b i f) a;;
fora 1 10 (fun a i -> a+i);;
Посчитаем сумму чисел от 1 до 10:
А сумму 1+...+x^n/n!
![Page 13: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/13.jpg)
13
©20
08 С
ошни
ков
Д.В
.
(* Следующее за 10 простое число *)whilel 10 (fun i -> not is_prime i);;
(* sin(sin(sin(x))) *)let sin3 x = reccall 3 sin x;;
let sin3 = reccall 3 sin;;
![Page 14: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/14.jpg)
14
©20
08 С
ошни
ков
Д.В
.
Линейная Вызов функции генерирует не
более одного рекурсивного вызова
Нелинейная (плохая)let rec fib a = if a<2 then 1 else fib (a-1) + fib (a-2);;
fib 4fib 4
fib 3fib 3 fib 2fib 2
fib 2fib 2 fib 1fib 1 fib 1fib 1 fib 0fib 0
fact 3fact 3
fact 3fact 3
fact 1fact 1
![Page 15: Функциональное программирование](https://reader036.vdocuments.us/reader036/viewer/2022062309/568150bd550346895dbedb5c/html5/thumbnails/15.jpg)
15
©20
08 С
ошни
ков
Д.В
.
Прямая Косвенная
A вызывает B; B вызывает C; С вызывает A Часто встречается при построении
компиляторов методом рекурсивного спуска
let rec A = … B … and B = … C … and C = … A …;;