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

15
Сошников Дмитрий Валерьевич к.ф.-м.н., доцент [email protected] Факультет инноваций и высоких технологий Московский физико-технический институт

Upload: marcy

Post on 21-Jan-2016

70 views

Category:

Documents


0 download

DESCRIPTION

Функциональное программирование. Факультет инноваций и высоких технологий Московский физико-технический институт. Лекция 6. Сопоставление с образцом. Рекурсия. Циклы. Сопоставление с образцом. type document = SSN of int | Passport of string;; type personx = string * int * document;; - PowerPoint PPT Presentation

TRANSCRIPT

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

Сошников Дмитрий Валерьевич

к.ф.-м.н., доцент[email protected]

Факультет инноваций и высоких технологий

Московский физико-технический институт

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

Лекция 6

Сопоставление с образцом. Рекурсия. Циклы

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

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: Функциональное программирование

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: Функциональное программирование

5

©20

08 С

ошни

ков

Д.В

.

Конструкции для определения лямбда-выражений:

fun Поддерживает несколько аргументов в

каррированной форме: fun x y -> … Не поддерживает pattern matching

function Поддерживает только один аргумент

(возможно, tuple) Поддерживает pattern matching с

несколькими вариантами описания

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

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: Функциональное программирование

7

©20

08 С

ошни

ков

Д.В

.

Определения в F# могут быть рекурсивными, т.е. в рамках «let rec»- определения возможно использовать определяемую функцию

В λ-исчислении напрямую понятия рекурсии нет – мы позднее узнаем, как определяется рекурсия в λ-исчислении

Рекурсия – зачастую единственный способ совершения итеративных действий

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

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: Функциональное программирование

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: Функциональное программирование

10

©20

08 С

ошни

ков

Д.В

.

print_n – типичная реализация цикла со счетчиком

Необходимо выполнить какое-то действие несколько раз, при этом переменная-счетчик меняется от a до b

Действие можно задать функцией int → unit

Функционал – функция, принимающая или возвращающая функцию

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

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: Функциональное программирование

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: Функциональное программирование

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: Функциональное программирование

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: Функциональное программирование

15

©20

08 С

ошни

ков

Д.В

.

Прямая Косвенная

A вызывает B; B вызывает C; С вызывает A Часто встречается при построении

компиляторов методом рекурсивного спуска

let rec A = … B … and B = … C … and C = … A …;;