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

Post on 11-Feb-2017

104 Views

Category:

Software

6 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

Александр Алексеев

Парадигмыпрограммирования

– Процедурное программирование– Объектно-ориентированное программирование– Функциональное программирование– Логическое программирование– и другие...

Процедурноепрограммирование

– Pascal– Си– и другие...

Языки процедурного программирования:

Объектно-ориентированное

программирование

– Java– C#– Delphi (Object Pascal)– C++– Python– Perl, Perl 6– PHP5– и многие другие

ООП-языки:

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

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

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

Все очень просто!

Основы(на примере Haskell)

data Bool = True | False

data Bool = True | False

positive :: Int → Boolpositive x = x > 0

data Bool = True | False

positive :: Int → Boolpositive x = x > 0

max :: (Ord a) => a → a → amax x y | x > y = x | otherwise = y

data Person = Person { firstName :: String, lastName :: String, birthYear :: Int } deriving (Show)

data Person = Person { firstName :: String, lastName :: String, birthYear :: Int } deriving (Show)

alex = Person { firstName = "Александр", lastName = "Алексеев", birthYear = 1988 }

class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y)

class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y)

instance Eq Person where x == y = birthYear x == birthYear y

class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y)

instance Eq Person where x == y = birthYear x == birthYear y x /= y = not (x == y)

anton = Person { firstName = "Антон", lastName = "Алексеев", birthYear = 1991 }

anton = Person { firstName = "Антон", lastName = "Алексеев", birthYear = 1991 }

alex == anton False

anton = Person { firstName = "Антон", lastName = "Алексеев", birthYear = 1991 }

alex == anton Falsealex == alex True

anton = Person { firstName = "Антон", lastName = "Алексеев", birthYear = 1991 }

alex == anton Falsealex == alex Trueanton == alex False

anton = Person { firstName = "Антон", lastName = "Алексеев", birthYear = 1991 }

alex == anton Falsealex == alex Trueanton == alex Falseanton /= alex True

instance Ord Person where compare x y = compare (birthYear y) (birthYear x)

instance Ord Person where compare x y = compare (birthYear y) (birthYear x)

instance Ord Person where x `compare` y = birthYear y `compare` birthYear x

instance Ord Person where compare x y = compare (birthYear y) (birthYear x)

instance Ord Person where x `compare` y = birthYear y `compare` birthYear x

max :: (Ord a) => a → a → a

instance Ord Person where compare x y = compare (birthYear y) (birthYear x)

instance Ord Person where x `compare` y = birthYear y `compare` birthYear x

max :: (Ord a) => a → a → a

max alex anton

instance Ord Person where compare x y = compare (birthYear y) (birthYear x)

instance Ord Person where x `compare` y = birthYear y `compare` birthYear x

max :: (Ord a) => a → a → a

max alex anton

birthYear (max alex anton) == 1988

Каррирование(англ. currying)

max :: (Ord a) => a → a → a

max :: (Ord a) => a → a → amax :: (Ord a) => a → (a → a)

max :: (Ord a) => a → a → amax :: (Ord a) => a → (a → a)

max' = max alex

max :: (Ord a) => a → a → amax :: (Ord a) => a → (a → a)

max' = max alexmax' :: Person → Person

max :: (Ord a) => a → a → amax :: (Ord a) => a → (a → a)

max' = max alexmax' :: Person → Person

max' anton :: Person

max :: (Ord a) => a → a → amax :: (Ord a) => a → (a → a)

max' = max alexmax' :: Person → Person

max' anton :: PersonbirthYear (max' anton) == 1988

Лямбда-функции

Лямбда-функции

(λ)

(\x y → x + y)

(\x y → x + y)(\x y → x + y) :: ?

(\x y → x + y)(\x y → x + y) :: Num a => a → a → a

(\x y → x + y)(\x y → x + y) :: Num a => a → a → a

(\x y → x + y) 3 4

(\x y → x + y)(\x y → x + y) :: Num a => a → a → a

(\x y → x + y) 3 4(\x y → x + y) 3 4 == 7

Кортежи

(1, 2)

(1, 2)('a', 'b')

(1, 2)('a', 'b')(1, 2, 3, 4)

(1, 2)('a', 'b')(1, 2, 3, 4)(1, 'a')

(1, 2)('a', 'b')(1, 2, 3, 4)(1, 'a')('a')

(1, 2)('a', 'b')(1, 2, 3, 4)(1, 'a')('a')( )

(1, 2)('a', 'b')(1, 2, 3, 4)(1, 'a')('a')( )(1, (2, 'a'), 3)

(1, 2)('a', 'b')(1, 2, 3, 4)(1, 'a')('a')( )(1, (2, 'a'), 3)

fst (1, 2) == 1

(1, 2)('a', 'b')(1, 2, 3, 4)(1, 'a')('a')( )(1, (2, 'a'), 3)

fst (1, 2) == 1snd (1, 2) == 2

(1, 2)('a', 'b')(1, 2, 3, 4)(1, 'a')('a')( )(1, (2, 'a'), 3)

fst (1, 2) == 1snd (1, 2) == 2snd (1, (2, 'a'), 3) == (2, 'a')

Списки

[1, 2, 3]['a', 'b', 'c'][ ][ [1, 2], [3, 4] ][ (1, 'a'), (2, 'b'), (3, 'c') ]

head :: [a] → ahead [4, 8, 15, 16, 23, 42] == 4

tail :: [a] → [a]tail [4, 8, 15, 16, 23, 42] == [8, 15, 16, 23, 42]

head :: [a] → ahead [4, 8, 15, 16, 23, 42] == 4

tail :: [a] → [a]tail [4, 8, 15, 16, 23, 42] == [8, 15, 16, 23, 42]

init :: [a] → [a]init [4, 8, 15, 16, 23, 42] == [4, 8, 15, 16, 23]

last :: [a] → alast [4, 8, 15, 16, 23, 42] == 42

length :: [a] → Intlength [4, 8, 15, 16, 23, 42] == 6

null :: [a] → Boolnull [ ] == True null [1, 2, 3] == False

reverse [1, 2, 3] == [3, 2, 1]take 3 [1, 2, 3, 4, 5] == [1, 2, 3]drop 3 [1, 2, 3, 4, 5] == [4, 5]sum [1, 2, 3, 4, 5] == 15[1, 2, 3] ++ [4, 5] == [1, 2, 3, 4, 5]

Генераторысписков,

интервалы,ленивые вычисления

[ x * 2 | x ← [1, 2, 3] ] == [2, 4, 6]pairs = [ (x, y) | x ← [1, 2], y ← ['a', 'b'] ]pairs == [ (1,'a'), (1,'b'), (2,'a'), (2,'b') ]

[ x * 2 | x ← [1, 2, 3] ] == [2, 4, 6]pairs = [ (x, y) | x ← [1, 2], y ← ['a', 'b'] ]pairs == [ (1,'a'), (1,'b'), (2,'a'), (2,'b') ]

[1..5] == [1, 2, 3, 4, 5][2,4..10] == [2, 4, 6, 8, 10][1..] == [1, 2, 3, 4, 5, 6, 7, 8, 9, …]take 3 [1..] == [1, 2, 3]

[ x * 2 | x ← [1, 2, 3] ] == [2, 4, 6]pairs = [ (x, y) | x ← [1, 2], y ← ['a', 'b'] ]pairs == [ (1,'a'), (1,'b'), (2,'a'), (2,'b') ]

[1..5] == [1, 2, 3, 4, 5][2,4..10] == [2, 4, 6, 8, 10][1..] == [1, 2, 3, 4, 5, 6, 7, 8, 9, …]take 3 [1..] == [1, 2, 3]

cycle [1, 2, 3] == [1, 2, 3, 1, 2, 3, 1, 2, 3, … ]take 5 $ cycle [1, 2, 3] == [1, 2, 3, 1, 2]

Функциивысшего порядка

filter :: (a -> Bool) -> [a] -> [a]

filter :: (a -> Bool) -> [a] -> [a]filter (\x -> x `mod` 2 == 0) [1..10] == [2, 4, 8, 10]

filter :: (a -> Bool) -> [a] -> [a]filter (\x -> x `mod` 2 == 0) [1..10] == [2, 4, 8, 10]

map :: (a -> b) -> [a] -> [b]

filter :: (a -> Bool) -> [a] -> [a]filter (\x -> x `mod` 2 == 0) [1..10] == [2, 4, 8, 10]

map :: (a -> b) -> [a] -> [b]map (\x → x + 5) [1,2,3] == [6,7,8]

filter :: (a -> Bool) -> [a] -> [a]filter (\x -> x `mod` 2 == 0) [1..10] == [2, 4, 8, 10]

map :: (a -> b) -> [a] -> [b]map (+5) [1,2,3] == [6,7,8]

filter :: (a -> Bool) -> [a] -> [a]filter (\x -> x `mod` 2 == 0) [1..10] == [2, 4, 8, 10]

map :: (a -> b) -> [a] -> [b]map (+5) [1,2,3] == [6,7,8]

foldl :: (a -> b -> a) -> a -> [b] -> a

filter :: (a -> Bool) -> [a] -> [a]filter (\x -> x `mod` 2 == 0) [1..10] == [2, 4, 8, 10]

map :: (a -> b) -> [a] -> [b]map (+5) [1,2,3] == [6,7,8]

foldl :: (a -> b -> a) -> a -> [b] -> afoldl (\s x -> x + s) 0 [1, 2, 3] == 6

filter :: (a -> Bool) -> [a] -> [a]filter (\x -> x `mod` 2 == 0) [1..10] == [2, 4, 8, 10]

map :: (a -> b) -> [a] -> [b]map (+5) [1,2,3] == [6,7,8]

foldl :: (a -> b -> a) -> a -> [b] -> afoldl (\s x -> x + s) 0 [1, 2, 3] == 6

sum = foldl (\s x -> x + s) 0

Пишемсобственные

функции

null' :: [a] → Bool

null' :: [a] → Boolnull' [ ] = True

null' :: [a] → Boolnull' [ ] = Truenull' _ = False

null' :: [a] → Boolnull' [ ] = Truenull' _ = False

head' :: [a] → a

null' :: [a] → Boolnull' [ ] = Truenull' _ = False

head' :: [a] → ahead' (x:xs) = x

null' :: [a] → Boolnull' [ ] = Truenull' _ = False

head' :: [a] → ahead' (x:xs) = xhead' _ = error 'Empty list!'

null' :: [a] → Boolnull' [ ] = Truenull' _ = False

head' :: [a] → ahead' (x:xs) = xhead' _ = error 'Empty list!'

[1, 2, 3] == (1:(2:(3:[])))

foldl' :: (a -> b -> a) -> a -> [b] -> a

foldl' :: (a -> b -> a) -> a -> [b] -> afoldl' func acc (x:xs) = foldl' func (func acc x) xs

foldl' :: (a -> b -> a) -> a -> [b] -> afoldl' func acc (x:xs) = foldl' func (func acc x) xsfoldl' _ acc _ = acc

foldl' :: (a -> b -> a) -> a -> [b] -> afoldl' func acc (x:xs) = foldl' func (func acc x) xsfoldl' _ acc _ = acc

elem' :: Eq a => a -> [a] -> Bool

foldl' :: (a -> b -> a) -> a -> [b] -> afoldl' func acc (x:xs) = foldl' func (func acc x) xsfoldl' _ acc _ = acc

elem' :: Eq a => a -> [a] -> Boolelem' x (y:yx) | x == y = True | ...

foldl' :: (a -> b -> a) -> a -> [b] -> afoldl' func acc (x:xs) = foldl' func (func acc x) xsfoldl' _ acc _ = acc

elem' :: Eq a => a -> [a] -> Boolelem' x (y:yx) | x == y = True | otherwise = elem' x yx

foldl' :: (a -> b -> a) -> a -> [b] -> afoldl' func acc (x:xs) = foldl' func (func acc x) xsfoldl' _ acc _ = acc

elem' :: Eq a => a -> [a] -> Boolelem' x (y:yx) | x == y = True | otherwise = elem' x yxelem' _ _ = False

foldl' :: (a -> b -> a) -> a -> [b] -> afoldl' func acc (x:xs) = foldl' func (func acc x) xsfoldl' _ acc _ = acc

elem' :: Eq a => a -> [a] -> Boolelem' x (y:yx) | x == y = True | otherwise = elem' x yxelem' _ _ = False

elem' 1 [1, 2, 3] == True

foldl' :: (a -> b -> a) -> a -> [b] -> afoldl' func acc (x:xs) = foldl' func (func acc x) xsfoldl' _ acc _ = acc

elem' :: Eq a => a -> [a] -> Boolelem' x (y:yx) | x == y = True | otherwise = elem' x yxelem' _ _ = False

elem' 1 [1, 2, 3] == True elem' 7 [1, 2, 3] == False

За кадром остались:

За кадром остались:– параметризованные типы

За кадром остались:– параметризованные типы– монады

За кадром остались:– параметризованные типы– монады– ввод/вывод

За кадром остались:– параметризованные типы– монады– ввод/вывод– аппликативные функторы

За кадром остались:– параметризованные типы– монады– ввод/вывод– аппликативные функторы– застежки

Зачем все это нужно:

Зачем все это нужно:– Настоящая кроссплатформенность

Зачем все это нужно:– Настоящая кроссплатформенность– Автоматическое управление памятью

Зачем все это нужно:– Настоящая кроссплатформенность– Автоматическое управление памятью– Отсутсвие побочных эффектов

Зачем все это нужно:– Настоящая кроссплатформенность– Автоматическое управление памятью– Отсутсвие побочных эффектов– Автоматическое распараллеливание

Зачем все это нужно:– Настоящая кроссплатформенность– Автоматическое управление памятью– Отсутсвие побочных эффектов– Автоматическое распараллеливание– Строгая типизация

Зачем все это нужно:– Настоящая кроссплатформенность– Автоматическое управление памятью– Отсутсвие побочных эффектов– Автоматическое распараллеливание– Строгая типизация– и не только

Насколько быстр Haskell?

Насколько быстр Haskell?

Что можно написать на Haskell?

Что можно написать на Haskell?– CLI-приложения (например, Darcs)

Что можно написать на Haskell?– CLI-приложения (например, Darcs)– GUI-приложения (wxHaskell, gtk2hs, etc)

Что можно написать на Haskell?– CLI-приложения (например, Darcs)– GUI-приложения (wxHaskell, gtk2hs, etc)– веб-приложения (Yesod, Happstack, etc)

Что можно написать на Haskell?– CLI-приложения (например, Darcs)– GUI-приложения (wxHaskell, gtk2hs, etc)– веб-приложения (Yesod, Happstack, etc)– компиляторы, парсеры (Alex, Happy)

Что можно написать на Haskell?– CLI-приложения (например, Darcs)– GUI-приложения (wxHaskell, gtk2hs, etc)– веб-приложения (Yesod, Happstack, etc)– компиляторы, парсеры (Alex, Happy)– модули ядра Linux

Что можно написать на Haskell?– CLI-приложения (например, Darcs)– GUI-приложения (wxHaskell, gtk2hs, etc)– веб-приложения (Yesod, Happstack, etc)– компиляторы, парсеры (Alex, Happy)– модули ядра Linux– и многое другое

Другие ФП-языки:

Другие ФП-языки:– Erlang

Другие ФП-языки:– Erlang– OCaml

Другие ФП-языки:– Erlang– OCaml– Standart ML

Другие ФП-языки:– Erlang– OCaml– Standart ML– Common Lisp

Другие ФП-языки:– Erlang– OCaml– Standart ML– Common Lisp– Scheme, Racket

Другие ФП-языки:– Erlang– OCaml– Standart ML– Common Lisp– Scheme, Racket– Clojure

Другие ФП-языки:– Erlang– OCaml– Standart ML– Common Lisp– Scheme, Racket– Clojure– и другие

Литературапо ФП

Подборка ссылок:

Подборка ссылок:– http://fprog.ru/planet/

Подборка ссылок:– http://fprog.ru/planet/– http://erlanger.ru/

Подборка ссылок:– http://fprog.ru/planet/– http://erlanger.ru/– http://it-talk.org/

Подборка ссылок:– http://fprog.ru/planet/– http://erlanger.ru/– http://it-talk.org/– http://groups.google.ru/group/haskell-russian

Подборка ссылок:– http://fprog.ru/planet/– http://erlanger.ru/– http://it-talk.org/– http://groups.google.ru/group/haskell-russian– http://groups.google.ru/group/erlang-russian

Подборка ссылок:– http://fprog.ru/planet/– http://erlanger.ru/– http://it-talk.org/– http://groups.google.ru/group/haskell-russian– http://groups.google.ru/group/erlang-russian– http://groups.google.ru/group/clojure-russian

Подборка ссылок:– http://fprog.ru/planet/– http://erlanger.ru/– http://it-talk.org/– http://groups.google.ru/group/haskell-russian– http://groups.google.ru/group/erlang-russian– http://groups.google.ru/group/clojure-russian– http://habrahabr.ru/hub/haskell

Подборка ссылок:– http://fprog.ru/planet/– http://erlanger.ru/– http://it-talk.org/– http://groups.google.ru/group/haskell-russian– http://groups.google.ru/group/erlang-russian– http://groups.google.ru/group/clojure-russian– http://habrahabr.ru/hub/haskell– http://goo.gl/VUvjk (эта презентация)

Спасибо за внимание!

Александр Алексеев

http://eax.me/

top related