SlideShare a Scribd company logo
Линзы
Комбинаторная манипуляция данными
Александр Гранин
graninas@gmail.com
1
data Contacts = Contacts {
contactEMail :: String,
contactSkype :: String }
data Person = Person {
personName :: String,
personSurname :: String,
personContacts :: Contacts }
data Account = CommonAccount {
accountPerson :: Person,
accountLogin :: String }
Person
Account
Contacts
contactEMail
contactSkype
2
3
updateAccountEMail account newMail = let
CommonAccount person login = account
Person name surname contacts = person
Contacts _ skype = contacts
newContacts = Contacts newMail skype
newPerson = Person name surname newContacts
newAccount = CommonAccount newPerson login
in newAccount
4
data Account =
CommonAccount {
accountPerson :: Person,
accountLogin :: String }
| PayedAccount {
accountPerson :: Person,
accountLogin :: String,
accountScores :: Int }
data Contacts = Contacts {
contactEMail :: String,
contactSkype :: String }
data Person = Person {
personName :: String,
personSurname :: String,
personContacts :: Contacts }
5
updateAccountEMail account newMail = let
CommonAccount person login = account
Person name surname contacts = person
Contacts _ skype = contacts
newContacts = Contacts newMail skype
newPerson = Person name surname newContacts
newAccount = CommonAccount newPerson login
in newAccount
?
6
updateAccountEMail account newMail = let
CommonAccount person login = account
Person name surname contacts = person
Contacts _ skype = contacts
newContacts = Contacts newMail skype
newPerson = Person name surname newContacts
newAccount = CommonAccount newPerson login
in newAccount
7
updateAccountEMail account newMail = case account of
CommonAccount p l = CommonAccount (updateP p newMail) l
PayedAccount p l s = PayedAccount (updateP p newMail) l s
where
updateP p mail = let
Person name surname contacts = p
Contacts _ skype = contacts
newContacts = Contacts mail skype
newPerson = Person name surname newContacts
in newPerson
8
updateAccountEMail account newMail = case account of
CommonAccount p l = CommonAccount (updateP p newMail) l
PayedAccount p l s = PayedAccount (updateP p newMail) l s
where
updateP p mail = let
Person name surname contacts = p
Contacts _ skype = contacts
newContacts = Contacts mail skype
newPerson = Person name surname newContacts
in newPerson
9
updateAccountEMail account newMail = let
person = accountPerson account
contacts = personContacts person
newContacts = contacts { contactEMail = newMail }
newPerson = person { personContacts = newContacts }
newAccount = account { accountPerson = newPerson }
in newAccount
getEMail contacts = contactEMail contacts
setEMail contacts mail = contacts { contactEMail = mail }
getContacts person = personContacts person
setContacts person contacts = person { personContacts = contacts }
getPerson account = accountPerson account
setPerson account person = account { accountPerson = person }
b = getB a
a = setB b a
10
getter :: A -> B
setter :: A -> B -> A
Линза = Геттер + Сеттер
lens :: (getter :: A -> B,
setter :: A -> B -> A)
eMailLens :: (Contacts -> String,
Contacts -> String -> Contacts)
eMailLens = (getEMail, setEMail)
where
getEMail contacts = contactEMail contacts
setEMail contacts mail = contacts {contactEMail = mail}
11
Комбинаторы view, set
view (getter, _) parent = getter parent
set (_, setter) parent value = setter parent value
> let contacts = Contacts "someone@null.ptr" "not_a_skype_account"
> view eMailLens contacts
"someone@null.ptr"
> set eMailLens contacts "dereference@null.ptr"
Contacts "dereference@null.ptr" "not_a_skype_account" 12
personLens = (getPerson, setPerson)
where
getPerson account = accountPerson account
setPerson account person = account {accountPerson = person}
contactLens = (getContacts, setContacts)
where
getContacts person = personContacts person
setContacts person contacts = person {personContacts = contacts}
13
Еще линзы
(getChild, setChild) . (getValue, setValue) = (getter, setter)
getter parent = getValue (getChild parent)
setter parent value = let
oldChild = getChild parent
newChild = setValue oldChild value
in setChild parent newChild
Композиция линз
14
Композиция линз - тоже линза
> let contacts = Contacts "someone@null.ptr" "not_a_skype_account"
> let person = Person “Some” “One” contacts
> view (contactLens . eMailLens) person
"someone@null.ptr"
> set (contactLens . eMailLens) person "dereference@null.ptr"
Person “Some” “One”
(Contacts "dereference@null.ptr" "not_a_skype_account") 15
> let contacts = Contacts "someone@null.ptr" "not_a_skype_account"
> let person = Person “Some” “One” contacts
> let account = PayedAccount person “login” 0
> view (eMailLens . contactLens . personLens) account
"someone@null.ptr"
> set (eMailLens . contactLens . personLens) account "42@nm.ru"
…………………………………………………………………………………
………………………………………………………………………………...
16
Композиция линз - тоже линза
Линзы в Haskell: библиотека lens
Автор - Edward Kmett
17
18
Fold Setter
Getter Traversal
Lens
Review
Prism
Iso Equality
data Contacts = Contacts {
_mail :: String,
_skype :: String }
data Person = Person {
_name :: String,
_surname :: String,
_contacts :: Contacts,
_skills :: [Skill] }
19
data Account =
CommonAccount {
_person :: Person,
_login :: String }
| PayedAccount {
_person :: Person,
_login :: String,
_scores :: Int }
data Skill = Cpp | CSharp | Haskell | Java | FSharp | Python
someoneContacts = Contacts "someone@null.ptr" "not_a_skype_account"
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
someOneAccount = PayedAccount someOnePerson "login" 0
grutContact = Contacts "i@am.grut" "grut"
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
grutAccount = CommonAccount grutPerson "bla"
accounts = [someOneAccount, grutAccount]
20
makeLenses ''Contacts
makeLenses ''Person
makeLenses ''Account
Создание линз (Template Haskell)
name Person ===> String
surname Person ===> String
contacts Person ===> Contacts
person Account ===> Person
scores Account ===> Int
………. ……….. ……….....
21
Getters, Setters
22
Операторы view (^.), set (^~)
23
> let contacts’ = Contacts "someone@null.ptr" "not_a_skype_account"
> let person’ = Person “Some” “One” contacts’ [Cpp, Haskell ]
> let account’ = PayedAccount person’ “login” 0
> let mailLens = person . contacts . mail
> view mailLens account’
"someone@null.ptr"
> (set mailLens account’ "42@nm.ru") ^. mailLens
"42@nm.ru"
> let contacts’ = Contacts "someone@null.ptr" "not_a_skype_account"
> let person’ = Person “Some” “One” contacts’ [Cpp, Haskell ]
> let account’ = PayedAccount person’ “login” 0
let mailLens = person . contacts . mail
> (over mailLens (map toUpper) account') ^. mailLens
"SOMEONE@NULL.PTR"
Оператор over
24
Folds
25
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> view (folded . person . skills) accounts
[Cpp,Haskell,FSharp]
26
Оператор folded
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> view (folded . person . surname) accounts
“OneGrut”
Оператор folded
27
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> view (folded . person . contacts) accounts
No instance for (Data.Monoid.Monoid Contacts)
arising from a use of ‘folded’
In the first argument of ‘(.)’, namely ‘folded’
In the first argument of ‘view’, namely
‘(folded . person . contacts)’
In the expression: view (folded . person . contacts) accounts
28
Оператор folded
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> toListOf (folded . person . contacts) accounts
[ Contacts {_mail = "someone@null.ptr", _skype = "not_a_skype_account"}
, Contacts {_mail = "i@am.grut", _skype = "grut"}]
29
Оператор toListOf
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> toListOf (folded . person . surname) accounts
[“One”, “Grut”]
30
Оператор toListOf
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> let onlyGrut = filtered (acc -> acc ^. person.surname == "Grut")
> view olnyGrut accounts
No instance for (Data.Monoid.Monoid Account)
arising from a use of ‘onlyGrut’
In the first argument of ‘view’, namely ‘onlyGrut’
In the expression: view onlyGrut accounts
In an equation for ‘it’: it = view onlyGrut accounts
31
Оператор filtered
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> let onlyGrut = filtered (acc -> acc ^. person.surname == "Grut")
> toListOf olnyGrut accounts
Couldn't match type ‘[Account]’ with ‘Account’
Expected type: Getting (Data.Monoid.Endo [Account])
[Account] Account
Actual type: Optic' (->) (Const (Data.Monoid.Endo
[Account])) Account Account
In the first argument of ‘toListOf’, namely ‘onlyGrut’
32
Оператор filtered
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> let onlyGrut = filtered (acc -> acc ^. person.surname == "Grut")
> toListOf (folded . olnyGrut) accounts
[ CommonAccount {_person = Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail =
"i@am.grut", _skype = "grut"}, _skills = [FSharp]}, _login = "bla"}]
33
Операторы filtered + folded
someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell]
grutPerson = Person "IAm" "Grut" grutContact [FSharp]
> let withN = filtered (acc -> ‘m’ `elem` acc ^. person.name)
> toListOf (folded . withN) accounts
[ PayedAccount {_person = Person {_name = "Some", _surname = "One", _contacts = Contacts {_mail =
"someone@null.ptr", _skype = "not_a_skype_account"}, _skills = [Cpp,Haskell]}, _login = "login", _scores =
0}
, CommonAccount {_person = Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail =
"i@am.grut", _skype = "grut"}, _skills = [FSharp]}, _login = "bla"}]
34
Еще пример filtered + folded
Prisms
35
> let result = Right grutPerson
> toListOf _Right result
[ Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail = "i@am.grut", _skype = "grut"},
_skills = [FSharp]} ]
> toListOf _Left result
[ ]
36
Операторы _Left, _Right
Комбинирование
37
> let result = Right grutPerson
> over (_Right . surname) (map toUpper) result
Right [ Person {_name = "IAm", _surname = "GRUT", _contacts = Contacts {_mail = "i@am.grut", _skype =
"grut"}, _skills = [FSharp]} ]
> over (_Left . surname) (map toUpper) result
Right [ Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail = "i@am.grut", _skype =
"grut"}, _skills = [FSharp]} ]
38
over + _Left, _Right
> let result = Right accounts
> let mailLens = person . contacts . mail
> over (_Right . traverse . mailLens) (map toUpper) result
Right
[ PayedAccount {_person = Person {_name = "Some", _surname = "One", _contacts = Contacts {_mail =
"SOMEONE@NULL.PTR", _skype = "not_a_skype_account"}, _skills = [Cpp,Haskell]}, _login = "login",
_scores = 0}
, CommonAccount {_person = Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail =
"I@AM.GRUT", _skype = "grut"}, _skills = [FSharp]}, _login = "bla"}]
39
over + traverse + _Right
#%%= **= //= //~ <<%@= <<.|.= <<^~ %= ...
#%%~ **~ <-= <#%= <<%@~ <<.|.~ <<||= %@= .=
#%= *= <-~ <#%~ <<%~ <<.~ <<||~ %@~ .>
#%~ *~ <. <#= <<&&= <<//= <<~ %~ .@=
#= += <.&.= <#~ <<&&~ <<//~ <>= & .@~
#~ +~ <.&.~ <%= <<**= <</>= <>~ &&= .|.=
%%= -= <.= <%@= <<**~ <</>~ <?= &&~ .|.~
%%@= -~ <.> <%@~ <<*= <<<.>= <?~ &~ .~
%%@~ .&.= <.>= <%~ <<*~ <<<.>~ <^= <.|.= <<-=
%%~ .&.~ <.>~ <&&= <<+= <<</>= <^^= <.|.~ <<-~
Тысячи операторов...
40
Сложные структуры данных
41
Zen
42
Спасибо за внимание!
Вопросы?
Александр Гранин
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) 43

More Related Content

What's hot

Penetration Testing with Improved Input Vector Identification
Penetration Testing with Improved Input Vector IdentificationPenetration Testing with Improved Input Vector Identification
Penetration Testing with Improved Input Vector Identification
Shauvik Roy Choudhary, Ph.D.
 
Conquering JSONB in PostgreSQL
Conquering JSONB in PostgreSQLConquering JSONB in PostgreSQL
Conquering JSONB in PostgreSQL
Ines Panker
 
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB
 
The love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinThe love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with Xamarin
Lorenz Cuno Klopfenstein
 
PureScript & Pux
PureScript & PuxPureScript & Pux
PureScript & Pux
Arthur Xavier
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
Michael Galpin
 
The Testing Games: Mocking, yay!
The Testing Games: Mocking, yay!The Testing Games: Mocking, yay!
The Testing Games: Mocking, yay!
Donny Wals
 
INSERCION DE REGISTROS DESDE VISUAL.NET A UNA BD DE SQL SERVER
INSERCION DE REGISTROS DESDE VISUAL.NET A UNA BD DE SQL SERVERINSERCION DE REGISTROS DESDE VISUAL.NET A UNA BD DE SQL SERVER
INSERCION DE REGISTROS DESDE VISUAL.NET A UNA BD DE SQL SERVER
Darwin Durand
 

What's hot (8)

Penetration Testing with Improved Input Vector Identification
Penetration Testing with Improved Input Vector IdentificationPenetration Testing with Improved Input Vector Identification
Penetration Testing with Improved Input Vector Identification
 
Conquering JSONB in PostgreSQL
Conquering JSONB in PostgreSQLConquering JSONB in PostgreSQL
Conquering JSONB in PostgreSQL
 
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
 
The love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinThe love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with Xamarin
 
PureScript & Pux
PureScript & PuxPureScript & Pux
PureScript & Pux
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
The Testing Games: Mocking, yay!
The Testing Games: Mocking, yay!The Testing Games: Mocking, yay!
The Testing Games: Mocking, yay!
 
INSERCION DE REGISTROS DESDE VISUAL.NET A UNA BD DE SQL SERVER
INSERCION DE REGISTROS DESDE VISUAL.NET A UNA BD DE SQL SERVERINSERCION DE REGISTROS DESDE VISUAL.NET A UNA BD DE SQL SERVER
INSERCION DE REGISTROS DESDE VISUAL.NET A UNA BD DE SQL SERVER
 

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
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)
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++
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)
 

Recently uploaded

Orca: Nocode Graphical Editor for Container Orchestration
Orca: Nocode Graphical Editor for Container OrchestrationOrca: Nocode Graphical Editor for Container Orchestration
Orca: Nocode Graphical Editor for Container Orchestration
Pedro J. Molina
 
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
safelyiotech
 
Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...
Paul Brebner
 
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
widenerjobeyrl638
 
What is Continuous Testing in DevOps - A Definitive Guide.pdf
What is Continuous Testing in DevOps - A Definitive Guide.pdfWhat is Continuous Testing in DevOps - A Definitive Guide.pdf
What is Continuous Testing in DevOps - A Definitive Guide.pdf
kalichargn70th171
 
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Paul Brebner
 
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
gapen1
 
Streamlining End-to-End Testing Automation
Streamlining End-to-End Testing AutomationStreamlining End-to-End Testing Automation
Streamlining End-to-End Testing Automation
Anand Bagmar
 
Software Test Automation - A Comprehensive Guide on Automated Testing.pdf
Software Test Automation - A Comprehensive Guide on Automated Testing.pdfSoftware Test Automation - A Comprehensive Guide on Automated Testing.pdf
Software Test Automation - A Comprehensive Guide on Automated Testing.pdf
kalichargn70th171
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
Tier1 app
 
ppt on the brain chip neuralink.pptx
ppt  on   the brain  chip neuralink.pptxppt  on   the brain  chip neuralink.pptx
ppt on the brain chip neuralink.pptx
Reetu63
 
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
Luigi Fugaro
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Flutter vs. React Native: A Detailed Comparison for App Development in 2024
Flutter vs. React Native: A Detailed Comparison for App Development in 2024Flutter vs. React Native: A Detailed Comparison for App Development in 2024
Flutter vs. React Native: A Detailed Comparison for App Development in 2024
dhavalvaghelanectarb
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio, Inc.
 
Microsoft-Power-Platform-Adoption-Planning.pptx
Microsoft-Power-Platform-Adoption-Planning.pptxMicrosoft-Power-Platform-Adoption-Planning.pptx
Microsoft-Power-Platform-Adoption-Planning.pptx
jrodriguezq3110
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
kalichargn70th171
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
Alberto Brandolini
 
Boost Your Savings with These Money Management Apps
Boost Your Savings with These Money Management AppsBoost Your Savings with These Money Management Apps
Boost Your Savings with These Money Management Apps
Jhone kinadey
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
Bert Jan Schrijver
 

Recently uploaded (20)

Orca: Nocode Graphical Editor for Container Orchestration
Orca: Nocode Graphical Editor for Container OrchestrationOrca: Nocode Graphical Editor for Container Orchestration
Orca: Nocode Graphical Editor for Container Orchestration
 
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
 
Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...
 
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
 
What is Continuous Testing in DevOps - A Definitive Guide.pdf
What is Continuous Testing in DevOps - A Definitive Guide.pdfWhat is Continuous Testing in DevOps - A Definitive Guide.pdf
What is Continuous Testing in DevOps - A Definitive Guide.pdf
 
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
 
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
 
Streamlining End-to-End Testing Automation
Streamlining End-to-End Testing AutomationStreamlining End-to-End Testing Automation
Streamlining End-to-End Testing Automation
 
Software Test Automation - A Comprehensive Guide on Automated Testing.pdf
Software Test Automation - A Comprehensive Guide on Automated Testing.pdfSoftware Test Automation - A Comprehensive Guide on Automated Testing.pdf
Software Test Automation - A Comprehensive Guide on Automated Testing.pdf
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
 
ppt on the brain chip neuralink.pptx
ppt  on   the brain  chip neuralink.pptxppt  on   the brain  chip neuralink.pptx
ppt on the brain chip neuralink.pptx
 
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Flutter vs. React Native: A Detailed Comparison for App Development in 2024
Flutter vs. React Native: A Detailed Comparison for App Development in 2024Flutter vs. React Native: A Detailed Comparison for App Development in 2024
Flutter vs. React Native: A Detailed Comparison for App Development in 2024
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
 
Microsoft-Power-Platform-Adoption-Planning.pptx
Microsoft-Power-Platform-Adoption-Planning.pptxMicrosoft-Power-Platform-Adoption-Planning.pptx
Microsoft-Power-Platform-Adoption-Planning.pptx
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
 
Boost Your Savings with These Money Management Apps
Boost Your Savings with These Money Management AppsBoost Your Savings with These Money Management Apps
Boost Your Savings with These Money Management Apps
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
 

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

  • 2. data Contacts = Contacts { contactEMail :: String, contactSkype :: String } data Person = Person { personName :: String, personSurname :: String, personContacts :: Contacts } data Account = CommonAccount { accountPerson :: Person, accountLogin :: String } Person Account Contacts contactEMail contactSkype 2
  • 3. 3 updateAccountEMail account newMail = let CommonAccount person login = account Person name surname contacts = person Contacts _ skype = contacts newContacts = Contacts newMail skype newPerson = Person name surname newContacts newAccount = CommonAccount newPerson login in newAccount
  • 4. 4 data Account = CommonAccount { accountPerson :: Person, accountLogin :: String } | PayedAccount { accountPerson :: Person, accountLogin :: String, accountScores :: Int } data Contacts = Contacts { contactEMail :: String, contactSkype :: String } data Person = Person { personName :: String, personSurname :: String, personContacts :: Contacts }
  • 5. 5 updateAccountEMail account newMail = let CommonAccount person login = account Person name surname contacts = person Contacts _ skype = contacts newContacts = Contacts newMail skype newPerson = Person name surname newContacts newAccount = CommonAccount newPerson login in newAccount ?
  • 6. 6 updateAccountEMail account newMail = let CommonAccount person login = account Person name surname contacts = person Contacts _ skype = contacts newContacts = Contacts newMail skype newPerson = Person name surname newContacts newAccount = CommonAccount newPerson login in newAccount
  • 7. 7 updateAccountEMail account newMail = case account of CommonAccount p l = CommonAccount (updateP p newMail) l PayedAccount p l s = PayedAccount (updateP p newMail) l s where updateP p mail = let Person name surname contacts = p Contacts _ skype = contacts newContacts = Contacts mail skype newPerson = Person name surname newContacts in newPerson
  • 8. 8 updateAccountEMail account newMail = case account of CommonAccount p l = CommonAccount (updateP p newMail) l PayedAccount p l s = PayedAccount (updateP p newMail) l s where updateP p mail = let Person name surname contacts = p Contacts _ skype = contacts newContacts = Contacts mail skype newPerson = Person name surname newContacts in newPerson
  • 9. 9 updateAccountEMail account newMail = let person = accountPerson account contacts = personContacts person newContacts = contacts { contactEMail = newMail } newPerson = person { personContacts = newContacts } newAccount = account { accountPerson = newPerson } in newAccount
  • 10. getEMail contacts = contactEMail contacts setEMail contacts mail = contacts { contactEMail = mail } getContacts person = personContacts person setContacts person contacts = person { personContacts = contacts } getPerson account = accountPerson account setPerson account person = account { accountPerson = person } b = getB a a = setB b a 10 getter :: A -> B setter :: A -> B -> A
  • 11. Линза = Геттер + Сеттер lens :: (getter :: A -> B, setter :: A -> B -> A) eMailLens :: (Contacts -> String, Contacts -> String -> Contacts) eMailLens = (getEMail, setEMail) where getEMail contacts = contactEMail contacts setEMail contacts mail = contacts {contactEMail = mail} 11
  • 12. Комбинаторы view, set view (getter, _) parent = getter parent set (_, setter) parent value = setter parent value > let contacts = Contacts "someone@null.ptr" "not_a_skype_account" > view eMailLens contacts "someone@null.ptr" > set eMailLens contacts "dereference@null.ptr" Contacts "dereference@null.ptr" "not_a_skype_account" 12
  • 13. personLens = (getPerson, setPerson) where getPerson account = accountPerson account setPerson account person = account {accountPerson = person} contactLens = (getContacts, setContacts) where getContacts person = personContacts person setContacts person contacts = person {personContacts = contacts} 13 Еще линзы
  • 14. (getChild, setChild) . (getValue, setValue) = (getter, setter) getter parent = getValue (getChild parent) setter parent value = let oldChild = getChild parent newChild = setValue oldChild value in setChild parent newChild Композиция линз 14
  • 15. Композиция линз - тоже линза > let contacts = Contacts "someone@null.ptr" "not_a_skype_account" > let person = Person “Some” “One” contacts > view (contactLens . eMailLens) person "someone@null.ptr" > set (contactLens . eMailLens) person "dereference@null.ptr" Person “Some” “One” (Contacts "dereference@null.ptr" "not_a_skype_account") 15
  • 16. > let contacts = Contacts "someone@null.ptr" "not_a_skype_account" > let person = Person “Some” “One” contacts > let account = PayedAccount person “login” 0 > view (eMailLens . contactLens . personLens) account "someone@null.ptr" > set (eMailLens . contactLens . personLens) account "42@nm.ru" ………………………………………………………………………………… ………………………………………………………………………………... 16 Композиция линз - тоже линза
  • 17. Линзы в Haskell: библиотека lens Автор - Edward Kmett 17
  • 19. data Contacts = Contacts { _mail :: String, _skype :: String } data Person = Person { _name :: String, _surname :: String, _contacts :: Contacts, _skills :: [Skill] } 19 data Account = CommonAccount { _person :: Person, _login :: String } | PayedAccount { _person :: Person, _login :: String, _scores :: Int } data Skill = Cpp | CSharp | Haskell | Java | FSharp | Python
  • 20. someoneContacts = Contacts "someone@null.ptr" "not_a_skype_account" someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] someOneAccount = PayedAccount someOnePerson "login" 0 grutContact = Contacts "i@am.grut" "grut" grutPerson = Person "IAm" "Grut" grutContact [FSharp] grutAccount = CommonAccount grutPerson "bla" accounts = [someOneAccount, grutAccount] 20
  • 21. makeLenses ''Contacts makeLenses ''Person makeLenses ''Account Создание линз (Template Haskell) name Person ===> String surname Person ===> String contacts Person ===> Contacts person Account ===> Person scores Account ===> Int ………. ……….. ………..... 21
  • 23. Операторы view (^.), set (^~) 23 > let contacts’ = Contacts "someone@null.ptr" "not_a_skype_account" > let person’ = Person “Some” “One” contacts’ [Cpp, Haskell ] > let account’ = PayedAccount person’ “login” 0 > let mailLens = person . contacts . mail > view mailLens account’ "someone@null.ptr" > (set mailLens account’ "42@nm.ru") ^. mailLens "42@nm.ru"
  • 24. > let contacts’ = Contacts "someone@null.ptr" "not_a_skype_account" > let person’ = Person “Some” “One” contacts’ [Cpp, Haskell ] > let account’ = PayedAccount person’ “login” 0 let mailLens = person . contacts . mail > (over mailLens (map toUpper) account') ^. mailLens "SOMEONE@NULL.PTR" Оператор over 24
  • 26. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > view (folded . person . skills) accounts [Cpp,Haskell,FSharp] 26 Оператор folded
  • 27. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > view (folded . person . surname) accounts “OneGrut” Оператор folded 27
  • 28. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > view (folded . person . contacts) accounts No instance for (Data.Monoid.Monoid Contacts) arising from a use of ‘folded’ In the first argument of ‘(.)’, namely ‘folded’ In the first argument of ‘view’, namely ‘(folded . person . contacts)’ In the expression: view (folded . person . contacts) accounts 28 Оператор folded
  • 29. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > toListOf (folded . person . contacts) accounts [ Contacts {_mail = "someone@null.ptr", _skype = "not_a_skype_account"} , Contacts {_mail = "i@am.grut", _skype = "grut"}] 29 Оператор toListOf
  • 30. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > toListOf (folded . person . surname) accounts [“One”, “Grut”] 30 Оператор toListOf
  • 31. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > let onlyGrut = filtered (acc -> acc ^. person.surname == "Grut") > view olnyGrut accounts No instance for (Data.Monoid.Monoid Account) arising from a use of ‘onlyGrut’ In the first argument of ‘view’, namely ‘onlyGrut’ In the expression: view onlyGrut accounts In an equation for ‘it’: it = view onlyGrut accounts 31 Оператор filtered
  • 32. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > let onlyGrut = filtered (acc -> acc ^. person.surname == "Grut") > toListOf olnyGrut accounts Couldn't match type ‘[Account]’ with ‘Account’ Expected type: Getting (Data.Monoid.Endo [Account]) [Account] Account Actual type: Optic' (->) (Const (Data.Monoid.Endo [Account])) Account Account In the first argument of ‘toListOf’, namely ‘onlyGrut’ 32 Оператор filtered
  • 33. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > let onlyGrut = filtered (acc -> acc ^. person.surname == "Grut") > toListOf (folded . olnyGrut) accounts [ CommonAccount {_person = Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail = "i@am.grut", _skype = "grut"}, _skills = [FSharp]}, _login = "bla"}] 33 Операторы filtered + folded
  • 34. someOnePerson = Person "Some" "One" someoneContacts [Cpp, Haskell] grutPerson = Person "IAm" "Grut" grutContact [FSharp] > let withN = filtered (acc -> ‘m’ `elem` acc ^. person.name) > toListOf (folded . withN) accounts [ PayedAccount {_person = Person {_name = "Some", _surname = "One", _contacts = Contacts {_mail = "someone@null.ptr", _skype = "not_a_skype_account"}, _skills = [Cpp,Haskell]}, _login = "login", _scores = 0} , CommonAccount {_person = Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail = "i@am.grut", _skype = "grut"}, _skills = [FSharp]}, _login = "bla"}] 34 Еще пример filtered + folded
  • 36. > let result = Right grutPerson > toListOf _Right result [ Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail = "i@am.grut", _skype = "grut"}, _skills = [FSharp]} ] > toListOf _Left result [ ] 36 Операторы _Left, _Right
  • 38. > let result = Right grutPerson > over (_Right . surname) (map toUpper) result Right [ Person {_name = "IAm", _surname = "GRUT", _contacts = Contacts {_mail = "i@am.grut", _skype = "grut"}, _skills = [FSharp]} ] > over (_Left . surname) (map toUpper) result Right [ Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail = "i@am.grut", _skype = "grut"}, _skills = [FSharp]} ] 38 over + _Left, _Right
  • 39. > let result = Right accounts > let mailLens = person . contacts . mail > over (_Right . traverse . mailLens) (map toUpper) result Right [ PayedAccount {_person = Person {_name = "Some", _surname = "One", _contacts = Contacts {_mail = "SOMEONE@NULL.PTR", _skype = "not_a_skype_account"}, _skills = [Cpp,Haskell]}, _login = "login", _scores = 0} , CommonAccount {_person = Person {_name = "IAm", _surname = "Grut", _contacts = Contacts {_mail = "I@AM.GRUT", _skype = "grut"}, _skills = [FSharp]}, _login = "bla"}] 39 over + traverse + _Right
  • 40. #%%= **= //= //~ <<%@= <<.|.= <<^~ %= ... #%%~ **~ <-= <#%= <<%@~ <<.|.~ <<||= %@= .= #%= *= <-~ <#%~ <<%~ <<.~ <<||~ %@~ .> #%~ *~ <. <#= <<&&= <<//= <<~ %~ .@= #= += <.&.= <#~ <<&&~ <<//~ <>= & .@~ #~ +~ <.&.~ <%= <<**= <</>= <>~ &&= .|.= %%= -= <.= <%@= <<**~ <</>~ <?= &&~ .|.~ %%@= -~ <.> <%@~ <<*= <<<.>= <?~ &~ .~ %%@~ .&.= <.>= <%~ <<*~ <<<.>~ <^= <.|.= <<-= %%~ .&.~ <.>~ <&&= <<+= <<</>= <^^= <.|.~ <<-~ Тысячи операторов... 40
  • 43. 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) 43