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

Alexander Granin
Alexander GraninSoftware Developer, Independent Consultant at Independent Consultant
Идиоматичный
функциональный код
Александр Гранин
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
1 of 37

Recommended

Лекция 8. Графы. Обходы графов by
Лекция 8. Графы. Обходы графовЛекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовMikhail Kurnosov
2.4K views50 slides
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t... by
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Mikhail Kurnosov
1.9K views71 slides
Лекция 3: Бинарный поиск. Связные списки by
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиMikhail Kurnosov
2.6K views28 slides
Функциональное программирование на F# by
Функциональное программирование на F#Функциональное программирование на F#
Функциональное программирование на F#akrakovetsky
1.8K views38 slides
Основы NumPy by
Основы NumPyОсновы NumPy
Основы NumPyTheoretical mechanics department
860 views49 slides
Python. Объектно-ориентированное программирование by
Python. Объектно-ориентированное программирование Python. Объектно-ориентированное программирование
Python. Объектно-ориентированное программирование Theoretical mechanics department
1.5K views39 slides

More Related Content

What's hot

Лекция 11. Методы разработки алгоритмов by
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовMikhail Kurnosov
1.9K views63 slides
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps) by
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Mikhail Kurnosov
1.6K views63 slides
Лекция 4. Префиксные деревья (tries, prefix trees) by
Лекция 4. Префиксные деревья (tries, prefix trees)Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)Mikhail Kurnosov
903 views43 slides
Лекция 6: Биномиальные кучи (Binomial heaps) by
Лекция 6: Биномиальные кучи (Binomial heaps)Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)Mikhail Kurnosov
4.3K views58 slides
Основы SciPy by
Основы SciPyОсновы SciPy
Основы SciPyTheoretical mechanics department
807 views57 slides
Лекция 2. Алгоритмы сортировки by
Лекция 2. Алгоритмы сортировкиЛекция 2. Алгоритмы сортировки
Лекция 2. Алгоритмы сортировкиMikhail Kurnosov
2.4K views35 slides

What's hot(20)

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

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

Java8. Innovations by
Java8. InnovationsJava8. Innovations
Java8. InnovationsNakraynikov Oleg
601 views36 slides
Pyton – пробуем функциональный стиль by
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPython Meetup
3.9K views50 slides
Haskell Type System with Dzmitry Ivashnev. by
Haskell Type System with Dzmitry Ivashnev.Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.Sergey Tihon
561 views64 slides
Мир Python функционалим с помощью библиотек by
Мир Python  функционалим с помощью библиотекМир Python  функционалим с помощью библиотек
Мир Python функционалим с помощью библиотекPyNSK
543 views53 slides
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014 by
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
4.5K views16 slides
DSLs in Lisp and Clojure by
DSLs in Lisp and ClojureDSLs in Lisp and Clojure
DSLs in Lisp and ClojureVasil Remeniuk
667 views31 slides

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

Pyton – пробуем функциональный стиль by Python Meetup
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
Python Meetup3.9K views
Haskell Type System with Dzmitry Ivashnev. by Sergey Tihon
Haskell Type System with Dzmitry Ivashnev.Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.
Sergey Tihon561 views
Мир Python функционалим с помощью библиотек by PyNSK
Мир Python  функционалим с помощью библиотекМир Python  функционалим с помощью библиотек
Мир Python функционалим с помощью библиотек
PyNSK543 views
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014 by Python Meetup
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Python Meetup4.5K views
Лекция о языке программирования Haskell by husniyarova
Лекция о языке программирования HaskellЛекция о языке программирования Haskell
Лекция о языке программирования Haskell
husniyarova748 views
Scala by DevDay
ScalaScala
Scala
DevDay847 views
Презентация на тему: Повторение курса информатики 7 класс by 2berkas
Презентация на тему: Повторение курса информатики 7 классПрезентация на тему: Повторение курса информатики 7 класс
Презентация на тему: Повторение курса информатики 7 класс
2berkas771 views
User Defined Materials in LS-DYNA by Yury Novozhilov
User Defined Materials in LS-DYNAUser Defined Materials in LS-DYNA
User Defined Materials in LS-DYNA
Yury Novozhilov2.2K views
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3... by pgdayrussia
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
pgdayrussia786 views
TMPA-2013 Dmitry Zaitsev by Iosif Itkin
TMPA-2013 Dmitry ZaitsevTMPA-2013 Dmitry Zaitsev
TMPA-2013 Dmitry Zaitsev
Iosif Itkin900 views
Использование GNU OCTAVE для инженерных и математических расчетов by Транслируем.бел
Использование GNU OCTAVE для инженерных и математических расчетовИспользование GNU OCTAVE для инженерных и математических расчетов
Использование GNU OCTAVE для инженерных и математических расчетов
8 встреча — Язык программирования Python (В. Ананьев) by Smolensk Computer Science Club
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели... by Ontico
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Ontico1.1K views

More from Alexander Granin

Concurrent applications with free monads and stm by
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stmAlexander Granin
208 views55 slides
Hierarchical free monads and software design in fp by
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fpAlexander Granin
161 views59 slides
Final tagless vs free monad by
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monadAlexander Granin
158 views74 slides
Monadic parsers in C++ by
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++Alexander Granin
579 views58 slides
The present and the future of functional programming in c++ by
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
343 views125 slides
О разработке десктопных приложений / About desktop development by
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentAlexander Granin
437 views22 slides

More from Alexander Granin(20)

Concurrent applications with free monads and stm by Alexander Granin
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
Alexander Granin208 views
Hierarchical free monads and software design in fp by Alexander Granin
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
Alexander Granin161 views
The present and the future of functional programming in c++ by 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++
Alexander Granin343 views
О разработке десктопных приложений / About desktop development by Alexander Granin
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
Alexander Granin437 views
Принципы и практики разработки ПО 2 / Principles and practices of software de... by Alexander Granin
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Alexander Granin133 views
Принципы и практики разработки ПО / Principles and practices of software deve... by Alexander Granin
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
Alexander Granin140 views
Закон Деметры / Demetra's law by Alexander Granin
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
Alexander Granin149 views
GitHub - зеркало разработчика by Alexander Granin
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
Alexander Granin958 views
The Present and The Future of Functional Programming in C++ by 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++
Alexander Granin86 views
Functional programming in C++ LambdaNsk by Alexander Granin
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
Alexander Granin464 views
Transition graph using free monads and existentials by Alexander Granin
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
Alexander Granin473 views
Software transactional memory. pure functional approach by Alexander Granin
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
Alexander Granin968 views
Вы не понимаете ФП / You don't understand FP by Alexander Granin
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
Alexander Granin144 views
Functional "Life": parallel cellular automata and comonads by Alexander Granin
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
Alexander Granin886 views
Functional microscope - Lenses in C++ by Alexander Granin
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
Alexander Granin1.7K views
Дизайн больших приложений в ФП by Alexander Granin
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
Alexander Granin761 views
Линзы - комбинаторная манипуляция данными by Alexander Granin
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
Alexander Granin389 views

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

  • 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