Эффективность рекурсивных функций. f 1 = f 2 = 1 f n = f n-1 + f n-2 при n > 2. -- Вычисление числа Фибоначчи, заданного порядковым номером fib :: Integer -> Integer fib 1 = 1 fib 2 = 1 fib n = fib (n-1) + fib (n-2). fib 6 fib 5 + fib 4 (fib 4 + fib 3) + fib 4 - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
1
Эффективность рекурсивных функций.
Кубенский А.А. Функциональное программирование.Глава 1. Элементы функционального программирования.
Кубенский А.А. Функциональное программирование.Глава 1. Элементы функционального программирования.
fib :: Integer -> Integerfib' :: Integer -> Integer -> Integer -> Integer -> Integerfib' n k fk fk1 | k == n = fk | k < n = fib' n (k+1) (fk+fk1) fk fib 1 = 1fib n = fib' n 2 1 1
factorial :: Integer -> Integerfactorial 0 = 1factorial n = n * factorial (n-1)
factorial :: Integer -> Integerfactorial' :: Integer -> Integer -> Integerfactorial n = factorial' n 1 -- (factorial' n f) == (f * n!)factorial' n f | n == 0 = f | n > 0 = factorial' (n-1) (n*f)
3
Списки в языке Haskell.
Кубенский А.А. Функциональное программирование.Глава 1. Элементы функционального программирования.
[] -- пустой список[1, 2, 3] -- список из заданых элементов1:[2, 3] -- присоединение головного элемента к списку1:(2:(3:[])) -- создание списка с помощью конструктора ':'[1..n] -- создание списка с помощью арифметической прогрессии[2, 4..20] -- арифметическая прогрессия с заданной разностью
Типы списков
[Char] -- список из символов (строка: "List" == ['L','i','s','t'])[(Char, Int)] -- список из кортежей: [('L', 1), ('i', 2), ('s', 3)][[Int]] -- список из списков: [[1, 2], [3, 5..10], []]
[Integer] -- список из целых чисел: [1..10]
Функция суммирования элементов спискаsumList :: [Integer] -> IntegersumList [] = 0sumList (x:s) = x + sumList s
height :: Tree a -> Intheight Empty = 0height (Node t1 _ t2) = 1 + max (height t1) (height t2)
11Кубенский А.А. Функциональное программирование.Глава 1. Элементы функционального программирования.
Сортировка с помощью двоичного дерева.
9
2
6
1
8
4
92 6
1
4
8
1
2
4
6
8
9
build flatten
sort :: (Ord a) => [a] -> [a]build :: (Ord a) => [a] -> Tree aflatten :: Tree a -> [a]
sort ls = flatten (build ls)
12Кубенский А.А. Функциональное программирование.Глава 1. Элементы функционального программирования.
Программа сортировки с помощью двоичного дерева.
data Tree a = Empty | Node (Tree a) a (Tree a)sort :: (Ord a) => [a] -> [a]build :: (Ord a) => [a] -> Tree ainsert :: (Ord a) => a -> Tree a -> Tree aflatten :: Tree a -> [a]sort ls = flatten (build ls)build [] = Emptybuild (e:ls) = insert e (build ls)insert e Empty = Node Empty e Emptyinsert e (Node t1 n t2) | e < n = Node (insert e t1) n t2 | e >= n = Node t1 n (insert e t2)flatten Empty = []flatten (Node t1 n t2) = (flatten t1) ++ (n : (flatten t2))
13
Глава 2. Средства функционального программирования
Кубенский А.А. Функциональное программирование.Глава 2. Средства функционального программирования.
18Кубенский А.А. Функциональное программирование.Глава 2. Средства функционального программирования.
Еще несколько полезных функций высших порядков.
-- "левая вставка" – еще один способ свертки спискаfoldl :: (b -> a -> b) -> b -> [a] -> bfoldl _ seed [] = seedfoldl f seed (x:ls) = foldl f (f seed x) ls
reverse :: [a] -> [a]reverse list = foldl app [] list where app l x = x:l
flip :: (a -> b -> c) -> (b -> a -> c)flip f = f' where f' x y = f y x
reverse :: [a] -> [a]reverse list = foldl (flip (:)) [] list
:: (b -> c) -> (a -> b) -> (a -> c) = fg where fg x = f (g x)
sqr :: (Num a) => a -> asqr a = a * apower4 :: (Num a) => a -> apower4 = comp sqr sqrsqr . sqr
compcomp f g(.)f . g
19Кубенский А.А. Функциональное программирование.Глава 2. Средства функционального программирования.
Еще несколько полезных функций высших порядков.
-- свертки без "зерна"foldl1, foldr1 :: (a -> a -> a) -> [a] -> afoldl1 _ [x] = xfoldl1 f (x:ls) = foldl f x lsfoldr1 _ [x] = xfoldr1 f (x:ls) = f x (foldr1 f ls)
all, any :: (a -> Bool) -> Boolall f list = foldr (&&) True (map f list)any f list = foldr (||) False (map f list)
takeWhile :: (a -> Bool) -> [a] -> [a]takeWhile _ [] = []takeWhile f (x:ls) | f x = x : takeWhile f ls | otherwise = []
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]zipWith _ [] _ = []zipWith _ _ [] = []zipWith f (e1:t1) (e2:t2) = (f e1 e2) : zipWith f t1 t2-- кстати, zip list1 list2 = zipWith (,) list1 list2
20Кубенский А.А. Функциональное программирование.Глава 2. Средства функционального программирования.
Свертки сложных структур данных.
data Tree a = Empty | Node (Tree a) a (Tree a)
A
B C
D E F
Правосторонний обход этого дерева:F, C, E, A, B, D
Функция, осуществляющая свертку в порядке правостороннего обхода:
foldTree :: (a -> b -> b) -> b -> Tree a -> bfoldTree _ seed Empty = seedfoldTree f seed (Node t1 n t2) = foldTree f (f n (foldTree f seed t2)) t1
t1 =
foldTree (++) seed t1 => D ++ (B ++ (A ++ (E ++ (C ++ (F ++ seed)))))
«Разглаживание» дерева с помощью foldTree:flatten :: Tree a -> [a]flatten t = foldTree (:) [] t
21Кубенский А.А. Функциональное программирование.Глава 2. Средства функционального программирования.
Сортировка с помощью дерева: используем функции высших порядков.
data Tree a = Empty | Node (Tree a) a (Tree a)sort :: (Ord a) => [a] -> [a]build :: (Ord a) => [a] -> Tree ainsert :: (Ord a) => a -> Tree a -> Tree aflatten :: Tree a -> [a]sort ls = flatten (build ls)insert e Empty = Node Empty e Emptyinsert e (Node t1 n t2) | e < n = Node (insert e t1) n t2 | e >= n = Node t1 n (insert e t2)
build list = foldr insert Empty list
flatten tree = foldTree (:) [] tree
foldTree :: (a -> b -> b) -> b -> Tree a -> bfoldTree _ seed Empty = seedfoldTree f seed (Node t1 n t2) = foldTree f (f n (foldTree f seed t2)) t1