SlideShare uma empresa Scribd logo
1 de 39
Линзы
Комбинаторная манипуляция данными
Александр Гранин
graninas@gmail.com
1
О себе
● Haskell, C++, немного C#
● Организатор сообщества LambdaNsk
● Доклады:
o Haskell. DevDay@2GIS
o ФП вчера и сегодня. TechTalks@NSU
o Функционально-декларативный дизайн на С++
o Идиоматичный ФП-код. LambdaNsk
2
● Очень кратко о ФП
● Линзы в Haskell
● Сценарии с использованием линз
● Линзы в других языках
План доклада
3
Функциональное программирование
● Функции высших порядков
● Лямбды
● Замыкания
● Иммутабельность
● Рекурсия
4
Функциональное программирование
● Функции высших порядков
● Лямбды
● Замыкания
● Иммутабельность
● Рекурсия
● Математические абстракции
5
data Credentials = Credentials {
credentialsLogin :: String,
credentialsPassword :: String }
Credentials
Login
Password
6
Простой алгебраический тип данных
updatePassword credentials newPassword = let
(Credentials login _) = credentials
in (Credentials login newPassword)
updatePassword2 credentials newPassword =
credentials { credentialsPassword = newPassword }
Изменение значения простого АТД
7
data Credentials = Credentials {
credentialsLogin :: String,
credentialsPassword :: String }
Credentials
Login
Password
data Credentials = Credentials {
credentialsLogin :: String,
credentialsPassword :: String }
data Person = Person {
personName :: String,
personSurname :: String,
personCredentials :: Credentials }
8
Более сложный АТД
Person
Credentials
Login
Password
Credentials
Login
Password
Credentials
Name
Surname
updatePersonPassword person newPass = let
credentials = personCredentials person
newCreds = credentials { credentialsPassword = newPass }
newPerson = person { personCredentials = newCreds }
in newPerson
9
Изменение более сложного АТД
data Credentials = Credentials {
credentialsLogin :: String,
credentialsPassword :: String }
data Person = Person {
personName :: String,
personSurname :: String,
personCredentials :: Credentials }
data Subscriber = Subscriber {
subscriberPerson :: Person,
subscriberTariffId :: Int }
Person
Subscriber
Credentials
Login
Password
10
А что, если?..
updateSubscriberPassword subscriber newPass = let
person = subscriberPerson subscriber
credentials = personCredentials person
newCreds = credentials { credentialsPassword = newPass }
newPerson = person { personCredentials = newCreds }
newSubscriber = subscriber { subscriberPerson = newPerson }
in newSubscriber
11
updateSubscriberPassword subscriber newPass = let
person = subscriberPerson subscriber
credentials = personCredentials person
newCreds = credentials { credentialsPassword = newPass }
newPerson = person { personCredentials = newCreds }
newSubscriber = subscriber { subscriberPerson = newPerson }
in newSubscriber
Getters
Setters
12
person = subscriberPerson subscriber
newSubscriber = subscriber { subscriberPerson = person }
credentials = personCredentials person
newPerson = person { personCredentials = credentials }
password = credentialsPassword credentials
newCreds = credentials { credentialsPassword = password }
b = getB a
a = setB b a
13
getPerson subscriber = subscriberPerson subscriber
setPerson subscriber person = subscriber { subscriberPerson = person }
getCredentials person = personCredentials person
setCredentials person creds = person { personCredentials = creds }
getPassword creds = credentialsPassword creds
setPassword creds pass = creds { credentialsPassword = pass }
b = getB a
a = setB b a
14
getter :: A -> B
setter :: A -> B -> A
Линза = Геттер + Сеттер
lens :: (getter :: A -> B,
setter :: A -> B -> A)
passwordLens :: (Credentials -> String,
Credentials -> String -> Credentials)
passwordLens = (getPass, setPass)
where
getPass creds = credentialsPassword creds
setPass creds newPass = creds {credentialsPassword = newPass}
15
Простые операторы view и set
view (getter, _) parent = getter parent
set (_, setter) parent value = setter parent value
> let myCredentials = Credentials "login" "pass"
> view passwordLens myCredentials
"pass"
> set passwordLens myCredentials "qwerty"
Credentials "login" "qwerty"
16
credentialsLens = (getCreds, setCreds)
where
getCreds person = personCredentials person
setCreds person newCreds = person {personCredentials = newCreds}
personLens = (getPerson, setPerson)
where
getPerson subscr = subscriberPerson subscr
setPerson subscr newPers = subscr {subscriberPerson = newPers}
Еще линзы
17
(getChild, setChild) . (getValue, setValue) = (getter, setter)
where
getter parent = getValue (getChild parent)
setter parent value = let
oldChild = getChild parent
newChild = setValue oldChild value
in setChild parent newChild
Линза . линза = линза
18
Композиция!
myCredentials = Credentials "login" "pass"
mePerson = Person "Alex" "Granin" myCredentials
> view (credentialsLens . passwordLens) mePerson
“pass”
> set (credentialsLens . passwordLens) mePerson “qwerty”
Person "Alex" "Granin" (Credentials "login" "qwerty")
Линза . линза = линза
19
Линзы в Haskell: библиотека lens
Автор - Edward Kmett
20
data ContactType = VK | FB | Twitter | Email
data Skill = Cpp | CSharp | Haskell | Java | FSharp | Python
data Person = Person {
_name :: String,
_surname :: String,
_contacts :: [(ContactType, String)],
_skills :: [Skill]
}
АТД Person
Person
Name
Surname
Contacts
Skills
21
type Presentation = String
data Attendee =
Speaker {
_person :: Person,
_visited :: [Presentation],
_presentationTitle :: String }
| Attendee {
_person :: Person,
_visited :: [Presentation] }
АТД Attendee
Attendee
Person
Name
Surname
Contacts
Skills
22
-- Template Haskell rocks:
makeLenses ''Person
makeLenses ''Attendee
Создание линз
_name name Person ===>
String
_surname surname Person ===>
String
_contacts contacts Person ===>
Contacts
_person person Attendee ===>
Person
_visited visited Attendee ===> 23
pete = Person "Pete" "Howard" [(FB, "pete")] [Java, Python]
peteAttendee = Attendee pete []
> _name (_person peteAttendee) -- Manual
“Pete”
> view (person.name) peteAttendee -- With lenses
“Pete”
> peteAttendee ^. (person.name) -- The same
“Pete”
Оператор view (^.)
24
> peteAttendee ^. person.skills
[Java,Python]
> itoList (peteAttendee ^. person.skills)
[(0,Java),(1,Python)]
> (itoList (peteAttendee ^. person.skills)) ^.. ix 1
[(1,Python)]
Операторы itoList, (^..) и ix
25
setAttendeeName att n = case att of
Speaker pers visit theme -> Speaker (setName pers) visit theme
Attendee pers visit -> Attendee (setName pers) visit
where
setName (Person _ s cts skls) = Person n s cts skls
setAttendeeName’ att n = set (person.name) "Jack" att
Оператор set
26
addContact att contact = case att of
Speaker pers visit theme -> Speaker (appendContact pers) visit theme
Attendee pers visit -> Attendee (appendContact pers) visit
where
appendContact (Person n s cts skls) = Person n s (contact : cts) skls
addContact' att contact =
over (person . contacts) (insert contact) att
Оператор over
27
#%%= **= //= //~ <<%@= <<.|.= <<^~ %= ...
#%%~ **~ <-= <#%= <<%@~ <<.|.~ <<||= %@= .=
#%= *= <-~ <#%~ <<%~ <<.~ <<||~ %@~ .>
#%~ *~ <. <#= <<&&= <<//= <<~ %~ .@=
#= += <.&.= <#~ <<&&~ <<//~ <>= & .@~
#~ +~ <.&.~ <%= <<**= <</>= <>~ &&= .|.=
%%= -= <.= <%@= <<**~ <</>~ <?= &&~ .|.~
%%@= -~ <.> <%@~ <<*= <<<.>= <?~ &~ .~
%%@~ .&.= <.>= <%~ <<*~ <<<.>~ <^= <.|.= <<-=
%%~ .&.~ <.>~ <&&= <<+= <<</>= <^^= <.|.~ <<-~
Тысячи их...
Zen 28
Сценарии с использованием линз
29
data Conference = Conference {
_attendees :: [Attendee],
_currentPresentation :: Presentation,
_conferenceTweets ::
[(Presentation, Person, String)]
}
АТД Conference
Attendee
Person
Conference
currentPresentation
conferenceTweets
30
pete = Person "Pete" "Howard" [facebook "pete"] [Java]
jakob = Person "Jakob" "Brown" [twitter "jab"] [Java, CSharp]
lana = Person "Lana" "Dell" [] [FSharp]
alex = Person "Alexander" "Granin" [vk "graninas"] [Haskell]
guru = Person "Real" "Guru" [] [Cpp, Java, CSharp, Haskell]
confAttendees = [ attendee pete, attendee jakob, attendee lana,
speaker alex "Lenses",
speaker guru “Multilanguage projects”]
conference = Conference confAttendees "" []
31
conferenceScenario :: State Conference ()
conferenceScenario = do
alex `tweeted` "Rush hour, sorry. #dev2dev"
beginPresentation "Multilanguage projects"
setListeners [pete, jakob, lana]
jakob `tweeted` "Great talk! #dev2dev"
lana `tweeted` "So technical. #dev2dev"
pete `tweeted` "#MLP 222 coming soon."
32
Сценарий “Конференция”
tweeted :: Person -> Msg -> State Conference ()
tweeted pers msg = if "#dev2dev" `isInfixOf` msg
then writeTweet pers msg
else return ()
writeTweet :: Person -> Msg -> State Conference ()
writeTweet pers msg = do
presentationName <- use currentPresentation
conferenceTweets %= insert (presentationName, pers, msg)
33
Сценарий “Твит”
beginPresentation :: Presentation -> State Conference ()
beginPresentation title = currentPresentation .= title
34
Сценарий “Начать доклад”
setListeners :: [Person] -> State Conference ()
setListeners persons = setVisited (attendees . onlyListeners persons)
onlyListeners :: Persons -> Traversal' [Attendee] Attendee
onlyListeners persons
= traversed . filtered (att -> (att ^. person) `elem` persons)
35
Сценарий “Задать слушателей”
conferenceScenario :: State Conference ()
conferenceScenario = do
alex `tweeted` "Rush hour, sorry. #conf"
beginPresentation "Multilanguage projects"
setListeners [pete, jakob, lana]
jakob `tweeted` "Great talk! #conf"
lana `tweeted` "So technical. #conf"
pete `tweeted` "#MLP 222 coming soon."
36
Сценарий “Конференция”
Линзы в других языках
● Haskell
○ Edward Kmett, “Lenses, Folds, and Traversals”
● Scalaz
○ Edward Kmett, “Lenses: A Functional Imperative”
● JavaScript
● Clojure
● C++ (!)
● … your language
37
38
Спасибо за внимание!
Вопросы?
Александр Гранин
graninas@gmail.com
beginPresentation :: Presentation -> State Conference ()
beginPresentation title = currentPresentation .= title
listeners :: [Person] -> State Conference ()
listeners perss = setVisited (attendees . onlyListeners perss)
where
setVisited atts = do
title <- use currentPresentation
atts.visited %= (insert title)
onlyListeners :: Persons -> Traversal' [Attendee] Attendee
onlyListeners ls = traversed . filtered (att -> att ^. person `elem` ls)
39

Mais conteúdo relacionado

Mais procurados

The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type Systemabrummett
 
Creating a compiler in Perl 6
Creating a compiler in Perl 6Creating a compiler in Perl 6
Creating a compiler in Perl 6Andrew Shitov
 
Caching and tuning fun for high scalability @ LOAD2012
Caching and tuning fun for high scalability @ LOAD2012Caching and tuning fun for high scalability @ LOAD2012
Caching and tuning fun for high scalability @ LOAD2012Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
Dropping ACID with MongoDB
Dropping ACID with MongoDBDropping ACID with MongoDB
Dropping ACID with MongoDBkchodorow
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in OptimizationDavid Golden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome TownRoss Tuck
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6garux
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegamehozayfa999
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm OldRoss Tuck
 
Wx::Perl::Smart
Wx::Perl::SmartWx::Perl::Smart
Wx::Perl::Smartlichtkind
 

Mais procurados (20)

The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type System
 
Creating a compiler in Perl 6
Creating a compiler in Perl 6Creating a compiler in Perl 6
Creating a compiler in Perl 6
 
Caching and tuning fun for high scalability @ LOAD2012
Caching and tuning fun for high scalability @ LOAD2012Caching and tuning fun for high scalability @ LOAD2012
Caching and tuning fun for high scalability @ LOAD2012
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
Inc
IncInc
Inc
 
Dropping ACID with MongoDB
Dropping ACID with MongoDBDropping ACID with MongoDB
Dropping ACID with MongoDB
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
 
Sass
SassSass
Sass
 
Wsomdp
WsomdpWsomdp
Wsomdp
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
 
Twitter codeigniter library
Twitter codeigniter libraryTwitter codeigniter library
Twitter codeigniter library
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
You Got Async in my PHP!
You Got Async in my PHP!You Got Async in my PHP!
You Got Async in my PHP!
 
Wx::Perl::Smart
Wx::Perl::SmartWx::Perl::Smart
Wx::Perl::Smart
 

Semelhante a Линзы - комбинаторная манипуляция данными (Dev2Dev)

Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languagesArthur Xavier
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScriptniklal
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaiMasters
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиAlexander Granin
 
PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018artgillespie
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Brian Hogan
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»SpbDotNet Community
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Powershell for Log Analysis and Data Crunching
 Powershell for Log Analysis and Data Crunching Powershell for Log Analysis and Data Crunching
Powershell for Log Analysis and Data CrunchingMichelle D'israeli
 
Beware: Sharp Tools
Beware: Sharp ToolsBeware: Sharp Tools
Beware: Sharp Toolschrismdp
 
Ruby and Rails by example
Ruby and Rails by exampleRuby and Rails by example
Ruby and Rails by examplebryanbibat
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Parsing with Perl6 Grammars
Parsing with Perl6 GrammarsParsing with Perl6 Grammars
Parsing with Perl6 Grammarsabrummett
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!Boy Baukema
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Ruby and Rails by Example (GeekCamp edition)
Ruby and Rails by Example (GeekCamp edition)Ruby and Rails by Example (GeekCamp edition)
Ruby and Rails by Example (GeekCamp edition)bryanbibat
 

Semelhante a Линзы - комбинаторная манипуляция данными (Dev2Dev) (20)

Why ruby
Why rubyWhy ruby
Why ruby
 
Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languages
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio Akita
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
 
PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Powershell for Log Analysis and Data Crunching
 Powershell for Log Analysis and Data Crunching Powershell for Log Analysis and Data Crunching
Powershell for Log Analysis and Data Crunching
 
Beware: Sharp Tools
Beware: Sharp ToolsBeware: Sharp Tools
Beware: Sharp Tools
 
Ruby and Rails by example
Ruby and Rails by exampleRuby and Rails by example
Ruby and Rails by example
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Parsing with Perl6 Grammars
Parsing with Perl6 GrammarsParsing with Perl6 Grammars
Parsing with Perl6 Grammars
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!
 
Tres Gemas De Ruby
Tres Gemas De RubyTres Gemas De Ruby
Tres Gemas De Ruby
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Ruby and Rails by Example (GeekCamp edition)
Ruby and Rails by Example (GeekCamp edition)Ruby and Rails by Example (GeekCamp edition)
Ruby and Rails by Example (GeekCamp edition)
 
Ams adapters
Ams adaptersAms adapters
Ams adapters
 

Mais de 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 stmAlexander 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 fpAlexander Granin
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monadAlexander 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 developmentAlexander 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 lawAlexander Granin
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FPAlexander 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++ LambdaNskAlexander 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 existentialsAlexander Granin
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approachAlexander Granin
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPAlexander 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 comonadsAlexander 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
 

Mais de 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++
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
Идиоматичный функциональный код
Идиоматичный функциональный кодИдиоматичный функциональный код
Идиоматичный функциональный код
 

Último

Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 

Último (20)

Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

Линзы - комбинаторная манипуляция данными (Dev2Dev)

  • 2. О себе ● Haskell, C++, немного C# ● Организатор сообщества LambdaNsk ● Доклады: o Haskell. DevDay@2GIS o ФП вчера и сегодня. TechTalks@NSU o Функционально-декларативный дизайн на С++ o Идиоматичный ФП-код. LambdaNsk 2
  • 3. ● Очень кратко о ФП ● Линзы в Haskell ● Сценарии с использованием линз ● Линзы в других языках План доклада 3
  • 4. Функциональное программирование ● Функции высших порядков ● Лямбды ● Замыкания ● Иммутабельность ● Рекурсия 4
  • 5. Функциональное программирование ● Функции высших порядков ● Лямбды ● Замыкания ● Иммутабельность ● Рекурсия ● Математические абстракции 5
  • 6. data Credentials = Credentials { credentialsLogin :: String, credentialsPassword :: String } Credentials Login Password 6 Простой алгебраический тип данных
  • 7. updatePassword credentials newPassword = let (Credentials login _) = credentials in (Credentials login newPassword) updatePassword2 credentials newPassword = credentials { credentialsPassword = newPassword } Изменение значения простого АТД 7 data Credentials = Credentials { credentialsLogin :: String, credentialsPassword :: String } Credentials Login Password
  • 8. data Credentials = Credentials { credentialsLogin :: String, credentialsPassword :: String } data Person = Person { personName :: String, personSurname :: String, personCredentials :: Credentials } 8 Более сложный АТД Person Credentials Login Password Credentials Login Password Credentials Name Surname
  • 9. updatePersonPassword person newPass = let credentials = personCredentials person newCreds = credentials { credentialsPassword = newPass } newPerson = person { personCredentials = newCreds } in newPerson 9 Изменение более сложного АТД
  • 10. data Credentials = Credentials { credentialsLogin :: String, credentialsPassword :: String } data Person = Person { personName :: String, personSurname :: String, personCredentials :: Credentials } data Subscriber = Subscriber { subscriberPerson :: Person, subscriberTariffId :: Int } Person Subscriber Credentials Login Password 10 А что, если?..
  • 11. updateSubscriberPassword subscriber newPass = let person = subscriberPerson subscriber credentials = personCredentials person newCreds = credentials { credentialsPassword = newPass } newPerson = person { personCredentials = newCreds } newSubscriber = subscriber { subscriberPerson = newPerson } in newSubscriber 11
  • 12. updateSubscriberPassword subscriber newPass = let person = subscriberPerson subscriber credentials = personCredentials person newCreds = credentials { credentialsPassword = newPass } newPerson = person { personCredentials = newCreds } newSubscriber = subscriber { subscriberPerson = newPerson } in newSubscriber Getters Setters 12
  • 13. person = subscriberPerson subscriber newSubscriber = subscriber { subscriberPerson = person } credentials = personCredentials person newPerson = person { personCredentials = credentials } password = credentialsPassword credentials newCreds = credentials { credentialsPassword = password } b = getB a a = setB b a 13
  • 14. getPerson subscriber = subscriberPerson subscriber setPerson subscriber person = subscriber { subscriberPerson = person } getCredentials person = personCredentials person setCredentials person creds = person { personCredentials = creds } getPassword creds = credentialsPassword creds setPassword creds pass = creds { credentialsPassword = pass } b = getB a a = setB b a 14 getter :: A -> B setter :: A -> B -> A
  • 15. Линза = Геттер + Сеттер lens :: (getter :: A -> B, setter :: A -> B -> A) passwordLens :: (Credentials -> String, Credentials -> String -> Credentials) passwordLens = (getPass, setPass) where getPass creds = credentialsPassword creds setPass creds newPass = creds {credentialsPassword = newPass} 15
  • 16. Простые операторы view и set view (getter, _) parent = getter parent set (_, setter) parent value = setter parent value > let myCredentials = Credentials "login" "pass" > view passwordLens myCredentials "pass" > set passwordLens myCredentials "qwerty" Credentials "login" "qwerty" 16
  • 17. credentialsLens = (getCreds, setCreds) where getCreds person = personCredentials person setCreds person newCreds = person {personCredentials = newCreds} personLens = (getPerson, setPerson) where getPerson subscr = subscriberPerson subscr setPerson subscr newPers = subscr {subscriberPerson = newPers} Еще линзы 17
  • 18. (getChild, setChild) . (getValue, setValue) = (getter, setter) where getter parent = getValue (getChild parent) setter parent value = let oldChild = getChild parent newChild = setValue oldChild value in setChild parent newChild Линза . линза = линза 18 Композиция!
  • 19. myCredentials = Credentials "login" "pass" mePerson = Person "Alex" "Granin" myCredentials > view (credentialsLens . passwordLens) mePerson “pass” > set (credentialsLens . passwordLens) mePerson “qwerty” Person "Alex" "Granin" (Credentials "login" "qwerty") Линза . линза = линза 19
  • 20. Линзы в Haskell: библиотека lens Автор - Edward Kmett 20
  • 21. data ContactType = VK | FB | Twitter | Email data Skill = Cpp | CSharp | Haskell | Java | FSharp | Python data Person = Person { _name :: String, _surname :: String, _contacts :: [(ContactType, String)], _skills :: [Skill] } АТД Person Person Name Surname Contacts Skills 21
  • 22. type Presentation = String data Attendee = Speaker { _person :: Person, _visited :: [Presentation], _presentationTitle :: String } | Attendee { _person :: Person, _visited :: [Presentation] } АТД Attendee Attendee Person Name Surname Contacts Skills 22
  • 23. -- Template Haskell rocks: makeLenses ''Person makeLenses ''Attendee Создание линз _name name Person ===> String _surname surname Person ===> String _contacts contacts Person ===> Contacts _person person Attendee ===> Person _visited visited Attendee ===> 23
  • 24. pete = Person "Pete" "Howard" [(FB, "pete")] [Java, Python] peteAttendee = Attendee pete [] > _name (_person peteAttendee) -- Manual “Pete” > view (person.name) peteAttendee -- With lenses “Pete” > peteAttendee ^. (person.name) -- The same “Pete” Оператор view (^.) 24
  • 25. > peteAttendee ^. person.skills [Java,Python] > itoList (peteAttendee ^. person.skills) [(0,Java),(1,Python)] > (itoList (peteAttendee ^. person.skills)) ^.. ix 1 [(1,Python)] Операторы itoList, (^..) и ix 25
  • 26. setAttendeeName att n = case att of Speaker pers visit theme -> Speaker (setName pers) visit theme Attendee pers visit -> Attendee (setName pers) visit where setName (Person _ s cts skls) = Person n s cts skls setAttendeeName’ att n = set (person.name) "Jack" att Оператор set 26
  • 27. addContact att contact = case att of Speaker pers visit theme -> Speaker (appendContact pers) visit theme Attendee pers visit -> Attendee (appendContact pers) visit where appendContact (Person n s cts skls) = Person n s (contact : cts) skls addContact' att contact = over (person . contacts) (insert contact) att Оператор over 27
  • 28. #%%= **= //= //~ <<%@= <<.|.= <<^~ %= ... #%%~ **~ <-= <#%= <<%@~ <<.|.~ <<||= %@= .= #%= *= <-~ <#%~ <<%~ <<.~ <<||~ %@~ .> #%~ *~ <. <#= <<&&= <<//= <<~ %~ .@= #= += <.&.= <#~ <<&&~ <<//~ <>= & .@~ #~ +~ <.&.~ <%= <<**= <</>= <>~ &&= .|.= %%= -= <.= <%@= <<**~ <</>~ <?= &&~ .|.~ %%@= -~ <.> <%@~ <<*= <<<.>= <?~ &~ .~ %%@~ .&.= <.>= <%~ <<*~ <<<.>~ <^= <.|.= <<-= %%~ .&.~ <.>~ <&&= <<+= <<</>= <^^= <.|.~ <<-~ Тысячи их... Zen 28
  • 30. data Conference = Conference { _attendees :: [Attendee], _currentPresentation :: Presentation, _conferenceTweets :: [(Presentation, Person, String)] } АТД Conference Attendee Person Conference currentPresentation conferenceTweets 30
  • 31. pete = Person "Pete" "Howard" [facebook "pete"] [Java] jakob = Person "Jakob" "Brown" [twitter "jab"] [Java, CSharp] lana = Person "Lana" "Dell" [] [FSharp] alex = Person "Alexander" "Granin" [vk "graninas"] [Haskell] guru = Person "Real" "Guru" [] [Cpp, Java, CSharp, Haskell] confAttendees = [ attendee pete, attendee jakob, attendee lana, speaker alex "Lenses", speaker guru “Multilanguage projects”] conference = Conference confAttendees "" [] 31
  • 32. conferenceScenario :: State Conference () conferenceScenario = do alex `tweeted` "Rush hour, sorry. #dev2dev" beginPresentation "Multilanguage projects" setListeners [pete, jakob, lana] jakob `tweeted` "Great talk! #dev2dev" lana `tweeted` "So technical. #dev2dev" pete `tweeted` "#MLP 222 coming soon." 32 Сценарий “Конференция”
  • 33. tweeted :: Person -> Msg -> State Conference () tweeted pers msg = if "#dev2dev" `isInfixOf` msg then writeTweet pers msg else return () writeTweet :: Person -> Msg -> State Conference () writeTweet pers msg = do presentationName <- use currentPresentation conferenceTweets %= insert (presentationName, pers, msg) 33 Сценарий “Твит”
  • 34. beginPresentation :: Presentation -> State Conference () beginPresentation title = currentPresentation .= title 34 Сценарий “Начать доклад”
  • 35. setListeners :: [Person] -> State Conference () setListeners persons = setVisited (attendees . onlyListeners persons) onlyListeners :: Persons -> Traversal' [Attendee] Attendee onlyListeners persons = traversed . filtered (att -> (att ^. person) `elem` persons) 35 Сценарий “Задать слушателей”
  • 36. conferenceScenario :: State Conference () conferenceScenario = do alex `tweeted` "Rush hour, sorry. #conf" beginPresentation "Multilanguage projects" setListeners [pete, jakob, lana] jakob `tweeted` "Great talk! #conf" lana `tweeted` "So technical. #conf" pete `tweeted` "#MLP 222 coming soon." 36 Сценарий “Конференция”
  • 37. Линзы в других языках ● Haskell ○ Edward Kmett, “Lenses, Folds, and Traversals” ● Scalaz ○ Edward Kmett, “Lenses: A Functional Imperative” ● JavaScript ● Clojure ● C++ (!) ● … your language 37
  • 39. beginPresentation :: Presentation -> State Conference () beginPresentation title = currentPresentation .= title listeners :: [Person] -> State Conference () listeners perss = setVisited (attendees . onlyListeners perss) where setVisited atts = do title <- use currentPresentation atts.visited %= (insert title) onlyListeners :: Persons -> Traversal' [Attendee] Attendee onlyListeners ls = traversed . filtered (att -> att ^. person `elem` ls) 39