SlideShare a Scribd company logo
Идиоматичный
функциональный код
Александр Гранин
graninas@gmail.com
Изменяемое состояние
Присваивание
Сторонние эффекты
Методы, функции
Циклы
Базовые типы
Иммутабельность
Декларация
Чистые функции
Функции, лямбды
Рекурсия
Базовые типы
Императивное
программирование
Функциональное
программирование
Класс = поля + методы
Объект класса
Наследование, ассоциация
Функторы, делегаты
Интерфейсы
ООП-паттерны
Модуль = типы + функции
Значение АТД
Комбинаторы, композиция
Лямбды, ФВП, продолжения
Обобщение типов
???
Объектно -
ориентированное
программирование
Функциональное
программирование
Класс = поля + методы
Объект класса
Наследование, ассоциация
Функторы, делегаты
Интерфейсы
ООП-паттерны
Модуль = типы + функции
Значение АТД
Комбинаторы, композиция
Лямбды, ФВП, продолжения
Обобщение типов
Функциональные идиомы
Объектно -
ориентированное
программирование
Функциональное
программирование
Функциональные идиомы
● Foldable, Traversable
● Functors
● Applicative Functors
● Monoids
● Monads
● ...
● Existential types
● Lenses
● Zippers
● Comonads
● GATDs
● ...
Функциональные идиомы
● Foldable, Traversable
● Functors
● Applicative Functors
● Monoids
● Monads
● Existential types
● Lenses
● Zippers
● Comonads
● GATDs
В чем разница между понятиями
“ООП-паттерн” и “ФП-идиома”?
ООП-паттерн vs Идиома
Паттерн: подход “снаружи”.
Несколько классов связываются в единую
систему с обобщающими интерфейсами.
Идиома: подход “изнутри”.
Идиома структурирует данные, обобщает и
пополняет их свойства.
Zippers
http://design.vidanto.com/?p=225
Список
-- Список на АТД:
data List a = Empty | Cons a (List a)
myList1 = Cons 1 (Cons 2 (Cons 3 Empty))
-- Списки в Haskell:
myList1 = [1, 2, 3]
myList2 = 1 : 2 : 3 : []
myList3 = 1 : [2, 3]
http://learnyouahaskell.com/zippers
Zipper для списка
data Zipper a = Zip [a] a [a]
toLeft (Zip xs a (y:ys)) = Zip (a:xs) y ys
toRight (Zip (x:xs) a ys) = Zip xs x (a:ys)
extract (Zip _ a _) = a
http://learnyouahaskell.com/zippers
Zipper для списка
zipper = Zip [] 0 [1..10]
> toLeft zipper
Zip [0] 1 [2, 3, 4, 5, 6, 7, 8, 9, 10]
> extract (toLeft (toLeft zipper))
2
Zip [2, 1, 0] 3 [4..10]
Текущий элемент
Сохраненный Контекст
data Tree a = Empty | Node a (Tree a) (Tree a)
data Direction = L | R
modify :: (a -> a) -> Tree a -> [Direction] -> Tree a
Дерево
1
2
5 3
1
2
50 30
data Tree a = Empty | Node a (Tree a) (Tree a)
data Direction = L | R
modify :: (a -> a) -> Tree a -> [Direction] -> Tree a
newTree1 = modify (*10) myTree [R, L]
newTree2 = modify (*10) newTree1 [R, R]
Изменение дерева
1
2
50 30
data Tree a = Empty | Node a (Tree a) (Tree a)
data NodeCtx a = LCtx a (Tree a)
| RCtx a (Tree a)
data TreeZipper a = TZ (Tree a) [NodeCtx a]
extract (TZ (Node a _ _) _) = a
Zipper для дерева
goLeft :: TreeZipper a -> TreeZipper a
goLeft (TZ (Node a l r) ctxs) = (TZ l (LCtx a r : ctxs))
goRight :: TreeZipper a -> TreeZipper a
goRight (TZ (Node a l r) ctxs) = (TZ r (RCtx a l : ctxs))
goUp :: TreeZipper a -> TreeZipper a
goUp = ...
Zipper для дерева
2
35 RCtx 1
> goRight zipper
TZ (Node 2 (Node 5 Empty Empty)
(Node 3 Empty Empty))
[RCtx 1 Empty]
1
2
35
tree = Node 1
Empty
(Node 2
(Node 5 Empty Empty)
(Node 3 Empty Empty))
zipper = TZ tree []
fromZipper :: TreeZipper a -> Tree a
fromZipper (TZ cur []) = cur
fromZipper z = fromZipper (goUp z)
Сборка дерева
RCtx 1
LCtx 2 3
5
1
2
35
data TreeDir = U | L | R
modify :: (a -> a) -> TreeZipper a -> [TreeDir] -> TreeZipper a
modify f (TZ (Node a l r) ctxs) [] = TZ (Node (f a) l r) ctxs
modify f z (L:dirs) = modify f (goLeft z) dirs
modify f z (R:dirs) = modify f (goRight z) dirs
modify f z (U:dirs) = modify f (goUp z) dirs
Изменение дерева
tree = Node 1
Empty
(Node 2
(Node 5 Empty Empty)
(Node 3 Empty Empty))
zipper = TZ tree []
newZipper1 = modify (*10) zipper [R, L]
newZipper2 = modify (*10) newZipper1 [U, R]
newTree = fromZipper newZipper
Изменение дерева 1
2
5 3
1
2
50 30
Комонады
https://greyfog.files.wordpress.com/2010/02/esploso-cellular-
automata.jpg
“Жизнь” без идиом
type Cell = (Int, Int)
type Grid = [Cell]
step :: Grid -> Grid
step p = let
next all [] = []
next all cur@((aX, aY) : alives) =
[(x, y) | x <- lim aX, y <- lim aY, length (neighbours8 (x, y) all) == 3]
++ (next all alives)
alive all cell = length (neighbours8 cell all) `elem` [2,3]
in L.nub $ filter (alive p) p ++ (next p p)
“Жизнь” без идиом
type Cell = (Int, Int)
type Grid = [Cell]
step :: Grid -> Grid
step p = let
next all [] = []
next all cur@((aX, aY) : alives) =
[(x, y) | x <- lim aX, y <- lim aY, length (neighbours8 (x, y) all) == 3]
++ (next all alives)
alive all cell = length (neighbours8 cell all) `elem` [2,3]
in L.nub $ filter (alive p) p ++ (next p p)
这是什么?
“Жизнь” на монадах
type Cell = (Int, Int)
type Grid = [Cell]
step :: Grid -> Grid
step cells = do
(newCell, n) <- frequencies $ concatMap neighbours cells
guard $ (n == 3) || (n == 2 && newCell `elem` cells)
return newCell
http://rhnh.net/2012/01/02/conway's-game-of-life-in-haskell
“Жизнь” на комонадах и зипперах
data Universe a = Universe [a] a [a]
data Cell = Dead | Alive
newtype Grid = Grid (Universe (Universe Cell))
rule :: Grid Cell -> Cell
rule grid
| nc == 2 = extract grid
| nc == 3 = Alive
| otherwise = Dead
where nc = length $ filter (==Alive) (neighbours grid)
next grid = grid =>> rule
http://habrahabr.ru/post/225473/
Множество Кантора на комонадах
Правило вывода
type Segment = (Float, Float)
type Segments = [(Float, Float)]
cantorRule :: Segment -> Segments
cantorRule (x1, x2) = let
len = x2 - x1
oneThird = len / 3.0
in [(x1, x1 + oneThird), (x2 - oneThird, x2)]
Фрактал - список списков
cantorGen :: Segments -> Segments
cantorGen segs = concatMap cantorRule segs
fractal :: [Segments]
fractal = iterate cantorGen [(0.0, 0.9)]
> take 2 fractal
[ [(0.0,0.9)], [(0.0,0.3),(0.6,0.9)] ]
data Layer a = Layer a
comonadCantorRule :: Layer Segments -> Segments
comonadCantorRule layer = cantorGen (extract layer)
comonadCantorGen :: Layer Segments -> Layer Segments
comonadCantorGen layer = layer =>> comonadCantorRule
> take 2 $ iterate comonadCantorGen cantorLayer
[ Layer [(0.0,9.0)], Layer [(0.0,3.0),(6.0,9.0)] ]
Фрактал - список слоев
Определение комонады
class Functor w => Comonad w where
extract :: w a -> a
duplicate :: w a -> w (w a)
extend :: (w a -> b) -> w a -> w b
extend f = fmap f . duplicate
duplicate = extend id
(=>>) :: Comonad w => w a -> (w a -> b) -> w b
cx =>> rule = extend rule cx
Простейшая комонада Layer
data Layer a = Layer a
instance Functor Layer where
fmap f (Layer a) = Layer (f a)
instance Comonad Layer where
duplicate (Layer a) = Layer (Layer a) -- w a -> w (w a)
extract (Layer a) = a -- w a -> a
Layer
Segments
Layer
Segments
Layer
duplicate =
Layer
Segments Segmentsextract =
duplicate :: w a -> w (w a)
extract :: w a -> a
=
Layer
Segments
Layer
comonadRule =
Layer
Segments
Layer
Segments =>> comonadRule =
=>> :: w a -> (w a -> b) -> w b
comonadRule :: (w a -> b)
Layer
Segments
Layer
= fmap comonadRule =
Спасибо за внимание!
Александр Гранин
graninas@gmail.com
Зипперы - это комонады
http://habrahabr.ru/post/225473/
data Universe a = Universe [a] a [a]
left, right :: Universe a -> Universe a
left (Universe (a:as) x bs) = Universe as a (x:bs)
right (Universe as x (b:bs)) = Universe (x:as) b bs
extract :: Universe a -> a
extract (Universe _ x _) = x
duplicate :: Universe a -> Universe (Universe a)
duplicate u = Universe (tail $ iterate left u) u (tail $ iterate right u)
Зиппер зипперов чисел
universe = Universe [-1, -2..] 0 [1, 2..]
universeOfUniverses = duplicate universe
http://habrahabr.ru/post/225473/
1
2
35
> goLeft (goRight zipper)
TZ (Node 5 Empty Empty)
[ LCtx 2 (Node 3 Empty Empty)
, RCtx 1 Empty]
RCtx 1
LCtx 2 3
5

More Related Content

What's hot

Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмов
Mikhail Kurnosov
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Mikhail Kurnosov
 
Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)
Mikhail Kurnosov
 
Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)Mikhail Kurnosov
 
Основы SciPy
Основы SciPyОсновы SciPy
Лекция 2. Алгоритмы сортировки
Лекция 2. Алгоритмы сортировкиЛекция 2. Алгоритмы сортировки
Лекция 2. Алгоритмы сортировки
Mikhail Kurnosov
 
Лекция 9: Графы. Поиск кратчайшего пути в графе
Лекция 9: Графы. Поиск кратчайшего пути в графеЛекция 9: Графы. Поиск кратчайшего пути в графе
Лекция 9: Графы. Поиск кратчайшего пути в графеMikhail Kurnosov
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)
Mikhail Kurnosov
 
Лекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьЛекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьMikhail Kurnosov
 
Лекция 4. Префиксные деревья (Tries, prefix trees)
Лекция 4. Префиксные деревья (Tries, prefix trees)Лекция 4. Префиксные деревья (Tries, prefix trees)
Лекция 4. Префиксные деревья (Tries, prefix trees)
Mikhail Kurnosov
 
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Mikhail Kurnosov
 
Лекция 5. Бинарные деревья поиска
Лекция 5. Бинарные деревья поискаЛекция 5. Бинарные деревья поиска
Лекция 5. Бинарные деревья поиска
Mikhail Kurnosov
 
Лекция 8: Графы. Обходы графов
Лекция 8: Графы. Обходы графовЛекция 8: Графы. Обходы графов
Лекция 8: Графы. Обходы графовMikhail Kurnosov
 
Лекция 1. Анализ эффективности алгоритмов
Лекция 1. Анализ эффективности алгоритмовЛекция 1. Анализ эффективности алгоритмов
Лекция 1. Анализ эффективности алгоритмов
Mikhail Kurnosov
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимости
Mikhail Kurnosov
 
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Mikhail Kurnosov
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Mikhail Kurnosov
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Mikhail Kurnosov
 
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Mikhail Kurnosov
 
Лекция 4: Префиксные деревья (Tries, prefix trees)
Лекция 4: Префиксные деревья (Tries, prefix trees)Лекция 4: Префиксные деревья (Tries, prefix trees)
Лекция 4: Префиксные деревья (Tries, prefix trees)Mikhail Kurnosov
 

What's hot (20)

Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмов
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
 
Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)
 
Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)
 
Основы SciPy
Основы SciPyОсновы SciPy
Основы SciPy
 
Лекция 2. Алгоритмы сортировки
Лекция 2. Алгоритмы сортировкиЛекция 2. Алгоритмы сортировки
Лекция 2. Алгоритмы сортировки
 
Лекция 9: Графы. Поиск кратчайшего пути в графе
Лекция 9: Графы. Поиск кратчайшего пути в графеЛекция 9: Графы. Поиск кратчайшего пути в графе
Лекция 9: Графы. Поиск кратчайшего пути в графе
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)
 
Лекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьЛекция 4: Стек. Очередь
Лекция 4: Стек. Очередь
 
Лекция 4. Префиксные деревья (Tries, prefix trees)
Лекция 4. Префиксные деревья (Tries, prefix trees)Лекция 4. Префиксные деревья (Tries, prefix trees)
Лекция 4. Префиксные деревья (Tries, prefix trees)
 
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
 
Лекция 5. Бинарные деревья поиска
Лекция 5. Бинарные деревья поискаЛекция 5. Бинарные деревья поиска
Лекция 5. Бинарные деревья поиска
 
Лекция 8: Графы. Обходы графов
Лекция 8: Графы. Обходы графовЛекция 8: Графы. Обходы графов
Лекция 8: Графы. Обходы графов
 
Лекция 1. Анализ эффективности алгоритмов
Лекция 1. Анализ эффективности алгоритмовЛекция 1. Анализ эффективности алгоритмов
Лекция 1. Анализ эффективности алгоритмов
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимости
 
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировка
 
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
 
Лекция 4: Префиксные деревья (Tries, prefix trees)
Лекция 4: Префиксные деревья (Tries, prefix trees)Лекция 4: Префиксные деревья (Tries, prefix trees)
Лекция 4: Префиксные деревья (Tries, prefix trees)
 

Similar to Идиоматичный функциональный код

Java8. Innovations
Java8. InnovationsJava8. Innovations
Java8. Innovations
Nakraynikov Oleg
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
Python Meetup
 
Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.
Sergey Tihon
 
Мир Python функционалим с помощью библиотек
Мир Python  функционалим с помощью библиотекМир Python  функционалим с помощью библиотек
Мир Python функционалим с помощью библиотек
PyNSK
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Python Meetup
 
DSLs in Lisp and Clojure
DSLs in Lisp and ClojureDSLs in Lisp and Clojure
DSLs in Lisp and Clojure
Vasil Remeniuk
 
Лекция о языке программирования Haskell
Лекция о языке программирования HaskellЛекция о языке программирования Haskell
Лекция о языке программирования Haskell
husniyarova
 
Основы Python. Функции
Основы Python. ФункцииОсновы Python. Функции
Основы Python. Функции
Theoretical mechanics department
 
Презентация на тему: Повторение курса информатики 7 класс
Презентация на тему: Повторение курса информатики 7 классПрезентация на тему: Повторение курса информатики 7 класс
Презентация на тему: Повторение курса информатики 7 класс2berkas
 
Функциональное программирование.Списки. Функции высших порядков
Функциональное программирование.Списки. Функции высших порядковФункциональное программирование.Списки. Функции высших порядков
Функциональное программирование.Списки. Функции высших порядков
Система дистанционного обучения MyDLS
 
User Defined Materials in LS-DYNA
User Defined Materials in LS-DYNAUser Defined Materials in LS-DYNA
User Defined Materials in LS-DYNA
Yury Novozhilov
 
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
pgdayrussia
 
TMPA-2013 Dmitry Zaitsev
TMPA-2013 Dmitry ZaitsevTMPA-2013 Dmitry Zaitsev
TMPA-2013 Dmitry ZaitsevIosif Itkin
 
Использование GNU OCTAVE для инженерных и математических расчетов
Использование GNU OCTAVE для инженерных и математических расчетовИспользование GNU OCTAVE для инженерных и математических расчетов
Использование GNU OCTAVE для инженерных и математических расчетовТранслируем.бел
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)
Smolensk Computer Science Club
 
Charming python sc2-8
Charming python sc2-8Charming python sc2-8
Charming python sc2-8
Vladislav Ananev
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Ontico
 

Similar to Идиоматичный функциональный код (20)

Java8. Innovations
Java8. InnovationsJava8. Innovations
Java8. Innovations
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
 
Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.
 
Мир Python функционалим с помощью библиотек
Мир Python  функционалим с помощью библиотекМир Python  функционалим с помощью библиотек
Мир Python функционалим с помощью библиотек
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
 
DSLs in Lisp and Clojure
DSLs in Lisp and ClojureDSLs in Lisp and Clojure
DSLs in Lisp and Clojure
 
Лекция о языке программирования Haskell
Лекция о языке программирования HaskellЛекция о языке программирования Haskell
Лекция о языке программирования Haskell
 
Основы Python. Функции
Основы Python. ФункцииОсновы Python. Функции
Основы Python. Функции
 
Scala
ScalaScala
Scala
 
Презентация на тему: Повторение курса информатики 7 класс
Презентация на тему: Повторение курса информатики 7 классПрезентация на тему: Повторение курса информатики 7 класс
Презентация на тему: Повторение курса информатики 7 класс
 
Функциональное программирование.Списки. Функции высших порядков
Функциональное программирование.Списки. Функции высших порядковФункциональное программирование.Списки. Функции высших порядков
Функциональное программирование.Списки. Функции высших порядков
 
User Defined Materials in LS-DYNA
User Defined Materials in LS-DYNAUser Defined Materials in LS-DYNA
User Defined Materials in LS-DYNA
 
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
 
TMPA-2013 Dmitry Zaitsev
TMPA-2013 Dmitry ZaitsevTMPA-2013 Dmitry Zaitsev
TMPA-2013 Dmitry Zaitsev
 
Использование GNU OCTAVE для инженерных и математических расчетов
Использование GNU OCTAVE для инженерных и математических расчетовИспользование GNU OCTAVE для инженерных и математических расчетов
Использование GNU OCTAVE для инженерных и математических расчетов
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)
 
Charming python sc2-8
Charming python sc2-8Charming python sc2-8
Charming python sc2-8
 
Rgsu04
Rgsu04Rgsu04
Rgsu04
 
Rgsu04
Rgsu04Rgsu04
Rgsu04
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
 

More from Alexander Granin

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
Alexander Granin
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
Alexander Granin
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monad
Alexander Granin
 
Monadic parsers in C++
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++
Alexander Granin
 
The present and the future of functional programming in c++
The present and the future of functional programming in c++The present and the future of functional programming in c++
The present and the future of functional programming in c++
Alexander Granin
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
Alexander Granin
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Alexander Granin
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
Alexander Granin
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
Alexander Granin
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FP
Alexander Granin
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
Alexander Granin
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
Alexander Granin
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
Alexander Granin
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
Alexander Granin
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
Alexander Granin
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
Alexander Granin
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
Alexander Granin
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
Alexander Granin
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
Alexander Granin
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
Alexander Granin
 

More from Alexander Granin (20)

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monad
 
Monadic parsers in C++
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++
 
The present and the future of functional programming in c++
The present and the future of functional programming in c++The present and the future of functional programming in c++
The present and the future of functional programming in c++
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FP
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
 

Идиоматичный функциональный код

  • 2. Изменяемое состояние Присваивание Сторонние эффекты Методы, функции Циклы Базовые типы Иммутабельность Декларация Чистые функции Функции, лямбды Рекурсия Базовые типы Императивное программирование Функциональное программирование
  • 3. Класс = поля + методы Объект класса Наследование, ассоциация Функторы, делегаты Интерфейсы ООП-паттерны Модуль = типы + функции Значение АТД Комбинаторы, композиция Лямбды, ФВП, продолжения Обобщение типов ??? Объектно - ориентированное программирование Функциональное программирование
  • 4. Класс = поля + методы Объект класса Наследование, ассоциация Функторы, делегаты Интерфейсы ООП-паттерны Модуль = типы + функции Значение АТД Комбинаторы, композиция Лямбды, ФВП, продолжения Обобщение типов Функциональные идиомы Объектно - ориентированное программирование Функциональное программирование
  • 5. Функциональные идиомы ● Foldable, Traversable ● Functors ● Applicative Functors ● Monoids ● Monads ● ... ● Existential types ● Lenses ● Zippers ● Comonads ● GATDs ● ...
  • 6. Функциональные идиомы ● Foldable, Traversable ● Functors ● Applicative Functors ● Monoids ● Monads ● Existential types ● Lenses ● Zippers ● Comonads ● GATDs В чем разница между понятиями “ООП-паттерн” и “ФП-идиома”?
  • 7. ООП-паттерн vs Идиома Паттерн: подход “снаружи”. Несколько классов связываются в единую систему с обобщающими интерфейсами. Идиома: подход “изнутри”. Идиома структурирует данные, обобщает и пополняет их свойства.
  • 9. Список -- Список на АТД: data List a = Empty | Cons a (List a) myList1 = Cons 1 (Cons 2 (Cons 3 Empty)) -- Списки в Haskell: myList1 = [1, 2, 3] myList2 = 1 : 2 : 3 : [] myList3 = 1 : [2, 3] http://learnyouahaskell.com/zippers
  • 10. Zipper для списка data Zipper a = Zip [a] a [a] toLeft (Zip xs a (y:ys)) = Zip (a:xs) y ys toRight (Zip (x:xs) a ys) = Zip xs x (a:ys) extract (Zip _ a _) = a http://learnyouahaskell.com/zippers
  • 11. Zipper для списка zipper = Zip [] 0 [1..10] > toLeft zipper Zip [0] 1 [2, 3, 4, 5, 6, 7, 8, 9, 10] > extract (toLeft (toLeft zipper)) 2
  • 12. Zip [2, 1, 0] 3 [4..10] Текущий элемент Сохраненный Контекст
  • 13. data Tree a = Empty | Node a (Tree a) (Tree a) data Direction = L | R modify :: (a -> a) -> Tree a -> [Direction] -> Tree a Дерево 1 2 5 3 1 2 50 30
  • 14. data Tree a = Empty | Node a (Tree a) (Tree a) data Direction = L | R modify :: (a -> a) -> Tree a -> [Direction] -> Tree a newTree1 = modify (*10) myTree [R, L] newTree2 = modify (*10) newTree1 [R, R] Изменение дерева 1 2 50 30
  • 15. data Tree a = Empty | Node a (Tree a) (Tree a) data NodeCtx a = LCtx a (Tree a) | RCtx a (Tree a) data TreeZipper a = TZ (Tree a) [NodeCtx a] extract (TZ (Node a _ _) _) = a Zipper для дерева
  • 16. goLeft :: TreeZipper a -> TreeZipper a goLeft (TZ (Node a l r) ctxs) = (TZ l (LCtx a r : ctxs)) goRight :: TreeZipper a -> TreeZipper a goRight (TZ (Node a l r) ctxs) = (TZ r (RCtx a l : ctxs)) goUp :: TreeZipper a -> TreeZipper a goUp = ... Zipper для дерева
  • 17. 2 35 RCtx 1 > goRight zipper TZ (Node 2 (Node 5 Empty Empty) (Node 3 Empty Empty)) [RCtx 1 Empty] 1 2 35 tree = Node 1 Empty (Node 2 (Node 5 Empty Empty) (Node 3 Empty Empty)) zipper = TZ tree []
  • 18. fromZipper :: TreeZipper a -> Tree a fromZipper (TZ cur []) = cur fromZipper z = fromZipper (goUp z) Сборка дерева RCtx 1 LCtx 2 3 5 1 2 35
  • 19. data TreeDir = U | L | R modify :: (a -> a) -> TreeZipper a -> [TreeDir] -> TreeZipper a modify f (TZ (Node a l r) ctxs) [] = TZ (Node (f a) l r) ctxs modify f z (L:dirs) = modify f (goLeft z) dirs modify f z (R:dirs) = modify f (goRight z) dirs modify f z (U:dirs) = modify f (goUp z) dirs Изменение дерева
  • 20. tree = Node 1 Empty (Node 2 (Node 5 Empty Empty) (Node 3 Empty Empty)) zipper = TZ tree [] newZipper1 = modify (*10) zipper [R, L] newZipper2 = modify (*10) newZipper1 [U, R] newTree = fromZipper newZipper Изменение дерева 1 2 5 3 1 2 50 30
  • 22. “Жизнь” без идиом type Cell = (Int, Int) type Grid = [Cell] step :: Grid -> Grid step p = let next all [] = [] next all cur@((aX, aY) : alives) = [(x, y) | x <- lim aX, y <- lim aY, length (neighbours8 (x, y) all) == 3] ++ (next all alives) alive all cell = length (neighbours8 cell all) `elem` [2,3] in L.nub $ filter (alive p) p ++ (next p p)
  • 23. “Жизнь” без идиом type Cell = (Int, Int) type Grid = [Cell] step :: Grid -> Grid step p = let next all [] = [] next all cur@((aX, aY) : alives) = [(x, y) | x <- lim aX, y <- lim aY, length (neighbours8 (x, y) all) == 3] ++ (next all alives) alive all cell = length (neighbours8 cell all) `elem` [2,3] in L.nub $ filter (alive p) p ++ (next p p) 这是什么?
  • 24. “Жизнь” на монадах type Cell = (Int, Int) type Grid = [Cell] step :: Grid -> Grid step cells = do (newCell, n) <- frequencies $ concatMap neighbours cells guard $ (n == 3) || (n == 2 && newCell `elem` cells) return newCell http://rhnh.net/2012/01/02/conway's-game-of-life-in-haskell
  • 25. “Жизнь” на комонадах и зипперах data Universe a = Universe [a] a [a] data Cell = Dead | Alive newtype Grid = Grid (Universe (Universe Cell)) rule :: Grid Cell -> Cell rule grid | nc == 2 = extract grid | nc == 3 = Alive | otherwise = Dead where nc = length $ filter (==Alive) (neighbours grid) next grid = grid =>> rule http://habrahabr.ru/post/225473/
  • 27. Правило вывода type Segment = (Float, Float) type Segments = [(Float, Float)] cantorRule :: Segment -> Segments cantorRule (x1, x2) = let len = x2 - x1 oneThird = len / 3.0 in [(x1, x1 + oneThird), (x2 - oneThird, x2)]
  • 28. Фрактал - список списков cantorGen :: Segments -> Segments cantorGen segs = concatMap cantorRule segs fractal :: [Segments] fractal = iterate cantorGen [(0.0, 0.9)] > take 2 fractal [ [(0.0,0.9)], [(0.0,0.3),(0.6,0.9)] ]
  • 29. data Layer a = Layer a comonadCantorRule :: Layer Segments -> Segments comonadCantorRule layer = cantorGen (extract layer) comonadCantorGen :: Layer Segments -> Layer Segments comonadCantorGen layer = layer =>> comonadCantorRule > take 2 $ iterate comonadCantorGen cantorLayer [ Layer [(0.0,9.0)], Layer [(0.0,3.0),(6.0,9.0)] ] Фрактал - список слоев
  • 30. Определение комонады class Functor w => Comonad w where extract :: w a -> a duplicate :: w a -> w (w a) extend :: (w a -> b) -> w a -> w b extend f = fmap f . duplicate duplicate = extend id (=>>) :: Comonad w => w a -> (w a -> b) -> w b cx =>> rule = extend rule cx
  • 31. Простейшая комонада Layer data Layer a = Layer a instance Functor Layer where fmap f (Layer a) = Layer (f a) instance Comonad Layer where duplicate (Layer a) = Layer (Layer a) -- w a -> w (w a) extract (Layer a) = a -- w a -> a
  • 32. Layer Segments Layer Segments Layer duplicate = Layer Segments Segmentsextract = duplicate :: w a -> w (w a) extract :: w a -> a
  • 33. = Layer Segments Layer comonadRule = Layer Segments Layer Segments =>> comonadRule = =>> :: w a -> (w a -> b) -> w b comonadRule :: (w a -> b) Layer Segments Layer = fmap comonadRule =
  • 35. Зипперы - это комонады http://habrahabr.ru/post/225473/ data Universe a = Universe [a] a [a] left, right :: Universe a -> Universe a left (Universe (a:as) x bs) = Universe as a (x:bs) right (Universe as x (b:bs)) = Universe (x:as) b bs extract :: Universe a -> a extract (Universe _ x _) = x duplicate :: Universe a -> Universe (Universe a) duplicate u = Universe (tail $ iterate left u) u (tail $ iterate right u)
  • 36. Зиппер зипперов чисел universe = Universe [-1, -2..] 0 [1, 2..] universeOfUniverses = duplicate universe http://habrahabr.ru/post/225473/
  • 37. 1 2 35 > goLeft (goRight zipper) TZ (Node 5 Empty Empty) [ LCtx 2 (Node 3 Empty Empty) , RCtx 1 Empty] RCtx 1 LCtx 2 3 5