SlideShare a Scribd company logo
Essence
ofthe
iteratorpatternMarkus Klink, @joheinz, markus.klink@inoio.de
Goal
“Imperative iterations using the pattern have two
simultaneous aspects: mapping and accumulating.”
Jeremy Gibbons & Bruno C. d. S. Oliveira
Markus Klink, @joheinz, markus.klink@inoio.de
Functionalmappingand
accumulating
trait Traverse[F[_]] extends Functor[F] with Foldable[F] {
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]
}
trait Applicative[F[_]] extends Functor[F] {
def ap[A,B](fa: F[A])(f: F[A => B]) : F[B]
def pure(a: A) : F[A]
def map[A,B](fa: F[A])(f: A => B) : F[B] = ap(fa)(pure(f))
}
Traverse takes a structure F[A], injects each element
via the function f: A => G[B] into an Applicative
G[_] and combines the results into G[F[B] using the
applicative instance of G.
Markus Klink, @joheinz, markus.klink@inoio.de
Acloser look
trait Foldable[F[_]] {
def foldRight[A, B](fa: F[A], z: => B)(f: (A, B) => B): B
}
trait Traverse[F[_]] extends Functor[F] with Foldable[F] {
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]
}
Look at the similarities!
Markus Klink, @joheinz, markus.klink@inoio.de
Traversing is "almost" like
Folding:
» Look! No zero element:
def foldRight[A, B](fa: F[A], z: => B)(f: (A, B) => B): B
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]
» Look! B is wrapped in an Applicative and our F:
def foldRight[A, B](fa: F[A], z: => B)(f: (A, B) => B): B
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]
Markus Klink, @joheinz, markus.klink@inoio.de
Accumulating
Markus Klink, @joheinz, markus.klink@inoio.de
val l = List(1,2,3)
val result: Future[List[String]] = l.traverse(a => Future.successful { a.toString })
How?
// traverse implementation of List, G[_] is the future
override def traverse[G[_]: Applicative, A, B](fa: List[A])(f: (A) => G[B]): G[List[B]] = {
val emptyListInG: G[List[B]] = Applicative[G].pure(List.empty[B]) // if the list is empty we need a Future { List.empty() }
// f(a) gives us another G[B], which we can inject into B => B => Future[List[B]]
foldRight(fa, emptyListInG) { (a: A, fbs: G[List[B]]) => Applicative[G].apply2(f(a), fbs)(_ +: _) }
}
// applicative instance of Future, example...
override def ap[A,B](F: => Future[A])(f: => Future[A => B]) : Future[B] = {
for {
a <- F
g <- f
} yield { g(a) }
}
Markus Klink, @joheinz, markus.klink@inoio.de
Gibbons & Oliveiraclaimthatwe
can do:
val x : List[Char]= "1234".toList
val result : Int = x.traverse(c => ???)
assert(4 == result)
The claim is that we can accumulate values, or write
the length function just with Traverse/Applicative
Markus Klink, @joheinz, markus.klink@inoio.de
How?
» we need a result type G[List[Int]] which equals
Int
» G needs to be an applicative
» we need to calculate a sum of all the values.
» we need a zero value in case the list is empty,
because of ...
val emptyListInG: G[List[B]] =
Applicative[G].pure(List.empty[B])
Markus Klink, @joheinz, markus.klink@inoio.de
Each Monoid gives risetoan
applicative
trait Monoid[F] extends Semigroup[F] {
self =>
/**
* the identity element.
*/
def zero: F
def applicative: Applicative[Lambda[a => F]] = new Applicative[Lambda[a => F]] {
// mapping just returns ourselves
override def map[A, B](fa: F)(f: A => B) : F = fa
// putting any value into this Applicative will put the Monoid.zero in it
def pure[A](a: => A): F = self.zero
// Applying this Applicative combines each value with the append function.
def ap[A, B](fa: => F)(f: => F): F = self.append(f, fa)
}
Markus Klink, @joheinz, markus.klink@inoio.de
How2
Part of the trick is this type: Applicative[Lambda[a
=> F]]!
It means that we throw everything away and create a
type G[_] which behaves like F. So...
val x : List[Char]= "1234".toList
val charCounter : Applicative[Lambda[a => Int]] = Monoid[Int].applicative
// we just "reversed" the parameters of traverse
// the summing is done automatically via append
charCounter.traverse(x)(_ => 1)
Markus Klink, @joheinz, markus.klink@inoio.de
Counting lines
In the previous example we assigned each char in the
list to a 1 and let the Monoid do the work.
val x : List[Char] = "1233n1234n"
val lineCounter : Applicative[Lambda[a => Int]] = Monoid[Int].applicative
lineCounter.traverse(x){c => if (c == 'n') 1 else 0 }
Markus Klink, @joheinz, markus.klink@inoio.de
Products ofApplicatives
Doing bothatthe sametimewithinasingle
traversal
val x : List[Char]= "1234n1234n"
val counter : Applicative[Lambda[a => Int]] = Monoid[Int].applicative
val charLineApp : Applicative[Lambda[a => (Int, Int)]] =
counter.product[Lambda[a => Int](counter)
val (chars, lines) = counter.traverse(x){c => (1 -> if (c == 'n') 1 else 0 }
Markus Klink, @joheinz, markus.klink@inoio.de
Countingwords
Counting words cannot work on the current position
alone. We need to track changes from spaces to non
spaces to recognize the beginning of a new word.
def atWordStart(c: Char): State[Boolean, Int] = State { (prev: Boolean) =>
val cur = c != ' '
(cur, if (!prev && cur) 1 else 0)
}
val WordCount : Applicative[Lambda[a => Int]] =
State.stateMonad[Boolean].compose[Lambda[a => Int](counter)
val StateWordCount = WordCount.traverse(text)(c => atWordStart(c))
StateWordCount.eval(false)
Markus Klink, @joheinz, markus.klink@inoio.de
Usingthe productofall3
countersto implementwc
val AppCharLinesWord: Applicative[Lambda[a => ((Int, Int), State[Boolean, Int])]] =
Count // char count
.product[Lambda[a => Int]](Count) // line count
.product[Lambda[a => State[Boolean, Int]]](WordCount) // word count
val ((charCount, lineCount), wordCountState) = AppCharLinesWord.traverse(text)((c: Char) =>
((1, if (c == 'n') 1 else 0), atWordStart(c)))
val wordCount: Int = wordCountState.eval(false)
Markus Klink, @joheinz, markus.klink@inoio.de
Collecting some
state
and modifying
elements
Markus Klink, @joheinz, markus.klink@inoio.de
// start value
public Integer count = 0;
public Collection<Person> collection = ...;
for (e <- collection) {
// or we use an if
count = count + 1;
// side effecting function
// or we map into another collection
e.modify();
}
Obviously in a functional programming language, we
would not want to modify the collection but get back
a new collection.
We also would like to get the (stateful) counter
back.
Markus Klink, @joheinz, markus.klink@inoio.de
def collect[G[_]: Applicative, A, B](fa: F[A])(f: A => G[Unit])(g: A => B): G[F[B]] =
{
val G = implicitly[Applicative[G]]
val applicationFn : A => G[B] = a => G.ap(f(a))(G.pure((u: Unit) => g(a)))
self.traverse(fa)(applicationFn)
}
def collectS[S, A, B](fa: F[A])(f: A => State[S, Unit])(g: A => B): State[S, F[B]] =
{
collect[Lambda[a => State[S, a]], A, B](fa)(f)(g)
}
val list : List[Person] = ...
val stateMonad = State.stateMonad[Int]
val (counter, updatedList) = list.collectS{
a => for { count <- get; _ <- put(count + 1) } yield ()}(p => p.modify()).run(0)
Markus Klink, @joheinz, markus.klink@inoio.de
Modifying elements
depending on some
state
Markus Klink, @joheinz, markus.klink@inoio.de
// start value
public Collection<Person> collection = ...;
for (e <- collection) {
e.modify(stateful());
}
Now the modification depends on some state we are
collecting.
Markus Klink, @joheinz, markus.klink@inoio.de
def disperse[G[_]: Applicative, A, B, C](fa: F[A])(fb: G[B], g: A => B => C): G[F[C]] =
{
val G = implicitly[Applicative[G]]
val applicationFn: A => G[C] = a => G.ap(fb)(G.pure(g(a)))
self.traverse(fa)(applicationFn)
}
def disperseS[S, A, C](fa: F[A])(fb: State[S, S], g: A => S => C) : State[S,F[C]] =
{
disperse[Lambda[a => State[S, a]], A, S, C](fa)(fb, g)
}
Markus Klink, @joheinz, markus.klink@inoio.de
THANKS
Markus Klink, @joheinz, markus.klink@inoio.de
Some resources
http://etorreborre.blogspot.de/2011/06/essence-of-
iterator-pattern.html
Markus Klink, @joheinz, markus.klink@inoio.de

More Related Content

What's hot

Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
Hang Zhao
 
10 - Scala. Co-product type (sum type)
10 - Scala. Co-product type (sum type)10 - Scala. Co-product type (sum type)
10 - Scala. Co-product type (sum type)
Roman Brovko
 
CLASS XII COMPUTER SCIENCE MONTHLY TEST PAPER
CLASS XII COMPUTER SCIENCE MONTHLY TEST  PAPERCLASS XII COMPUTER SCIENCE MONTHLY TEST  PAPER
CLASS XII COMPUTER SCIENCE MONTHLY TEST PAPER
Rc Os
 
C programs Set 2
C programs Set 2C programs Set 2
C programs Set 2
Koshy Geoji
 
Qno 3 (a)
Qno 3 (a)Qno 3 (a)
statistical computation using R- an intro..
statistical computation using R- an intro..statistical computation using R- an intro..
statistical computation using R- an intro..
Kamarudheen KV
 
Qno 2 (c)
Qno 2 (c)Qno 2 (c)
Cs practical file
Cs practical fileCs practical file
Cs practical file
Shailendra Garg
 
Fp in scala part 1
Fp in scala part 1Fp in scala part 1
Fp in scala part 1
Hang Zhao
 
SAMSTAR: A Semi-automated Lexical Method to generate Star Schemas from an ERD
SAMSTAR: A Semi-automated Lexical Method to generate Star Schemas from an ERDSAMSTAR: A Semi-automated Lexical Method to generate Star Schemas from an ERD
SAMSTAR: A Semi-automated Lexical Method to generate Star Schemas from an ERD
The Children's Hospital of Philadelphia
 
Modules and Scripts- Python Assignment Help
Modules and Scripts- Python Assignment HelpModules and Scripts- Python Assignment Help
Modules and Scripts- Python Assignment Help
Anderson Silva
 
SupportVectorRegression
SupportVectorRegressionSupportVectorRegression
SupportVectorRegression
Daniel K
 
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
Philip Schwarz
 
Matlab integration
Matlab integrationMatlab integration
Matlab integration
pramodkumar1804
 
BIometrics- plotting DET and EER curve using Matlab
BIometrics- plotting DET and EER curve using MatlabBIometrics- plotting DET and EER curve using Matlab
BIometrics- plotting DET and EER curve using Matlab
Shiv Koppad
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
Philip Schwarz
 
An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using Haskell
Michel Rijnders
 
Rumus visual basic
Rumus visual basicRumus visual basic
Rumus visual basic
T. Astari
 
OPERATOR IN PYTHON-PART1
OPERATOR IN PYTHON-PART1OPERATOR IN PYTHON-PART1
OPERATOR IN PYTHON-PART1
vikram mahendra
 
Rethinking metrics: metrics 2.0 @ Lisa 2014
Rethinking metrics: metrics 2.0 @ Lisa 2014Rethinking metrics: metrics 2.0 @ Lisa 2014
Rethinking metrics: metrics 2.0 @ Lisa 2014
Dieter Plaetinck
 

What's hot (20)

Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
 
10 - Scala. Co-product type (sum type)
10 - Scala. Co-product type (sum type)10 - Scala. Co-product type (sum type)
10 - Scala. Co-product type (sum type)
 
CLASS XII COMPUTER SCIENCE MONTHLY TEST PAPER
CLASS XII COMPUTER SCIENCE MONTHLY TEST  PAPERCLASS XII COMPUTER SCIENCE MONTHLY TEST  PAPER
CLASS XII COMPUTER SCIENCE MONTHLY TEST PAPER
 
C programs Set 2
C programs Set 2C programs Set 2
C programs Set 2
 
Qno 3 (a)
Qno 3 (a)Qno 3 (a)
Qno 3 (a)
 
statistical computation using R- an intro..
statistical computation using R- an intro..statistical computation using R- an intro..
statistical computation using R- an intro..
 
Qno 2 (c)
Qno 2 (c)Qno 2 (c)
Qno 2 (c)
 
Cs practical file
Cs practical fileCs practical file
Cs practical file
 
Fp in scala part 1
Fp in scala part 1Fp in scala part 1
Fp in scala part 1
 
SAMSTAR: A Semi-automated Lexical Method to generate Star Schemas from an ERD
SAMSTAR: A Semi-automated Lexical Method to generate Star Schemas from an ERDSAMSTAR: A Semi-automated Lexical Method to generate Star Schemas from an ERD
SAMSTAR: A Semi-automated Lexical Method to generate Star Schemas from an ERD
 
Modules and Scripts- Python Assignment Help
Modules and Scripts- Python Assignment HelpModules and Scripts- Python Assignment Help
Modules and Scripts- Python Assignment Help
 
SupportVectorRegression
SupportVectorRegressionSupportVectorRegression
SupportVectorRegression
 
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
 
Matlab integration
Matlab integrationMatlab integration
Matlab integration
 
BIometrics- plotting DET and EER curve using Matlab
BIometrics- plotting DET and EER curve using MatlabBIometrics- plotting DET and EER curve using Matlab
BIometrics- plotting DET and EER curve using Matlab
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using Haskell
 
Rumus visual basic
Rumus visual basicRumus visual basic
Rumus visual basic
 
OPERATOR IN PYTHON-PART1
OPERATOR IN PYTHON-PART1OPERATOR IN PYTHON-PART1
OPERATOR IN PYTHON-PART1
 
Rethinking metrics: metrics 2.0 @ Lisa 2014
Rethinking metrics: metrics 2.0 @ Lisa 2014Rethinking metrics: metrics 2.0 @ Lisa 2014
Rethinking metrics: metrics 2.0 @ Lisa 2014
 

Viewers also liked

Matuura cpp
Matuura cppMatuura cpp
Matuura cpp
matuura_core
 
SPL fukuokaphp_1
SPL fukuokaphp_1SPL fukuokaphp_1
SPL fukuokaphp_1
ichikaway
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」
matuura_core
 
型! 型!
型! 型!型! 型!
型! 型!
真一 北原
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator Pattern
Eric Torreborre
 
Iterator Pattern
Iterator PatternIterator Pattern
Iterator Pattern
melbournepatterns
 

Viewers also liked (8)

Matuura cpp
Matuura cppMatuura cpp
Matuura cpp
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
SPL fukuokaphp_1
SPL fukuokaphp_1SPL fukuokaphp_1
SPL fukuokaphp_1
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」
 
Chakkason.pptx
Chakkason.pptxChakkason.pptx
Chakkason.pptx
 
型! 型!
型! 型!型! 型!
型! 型!
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator Pattern
 
Iterator Pattern
Iterator PatternIterator Pattern
Iterator Pattern
 

Similar to Essence of the iterator pattern

Monads do not Compose
Monads do not ComposeMonads do not Compose
Monads do not Compose
Philip Schwarz
 
(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads
Lawrence Evans
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami Patterns
Vasil Remeniuk
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
league
 
Building Functions
Building FunctionsBuilding Functions
Building Functions
fireants18
 
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Ruslan Shevchenko
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
Raymond Roestenburg
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
league
 
Monad and Algebraic Design in Functional Programming
Monad and Algebraic Design in Functional ProgrammingMonad and Algebraic Design in Functional Programming
Monad and Algebraic Design in Functional Programming
Namuk Park
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
John De Goes
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystified
Alessandro Lacava
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1
Philip Schwarz
 
Monad presentation scala as a category
Monad presentation   scala as a categoryMonad presentation   scala as a category
Monad presentation scala as a category
samthemonad
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
John De Goes
 
The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)
Eric Torreborre
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
Philip Schwarz
 
Composition birds-and-recursion
Composition birds-and-recursionComposition birds-and-recursion
Composition birds-and-recursion
David Atchley
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
Hang Zhao
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
Tapio Rautonen
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain Models
Debasish Ghosh
 

Similar to Essence of the iterator pattern (20)

Monads do not Compose
Monads do not ComposeMonads do not Compose
Monads do not Compose
 
(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami Patterns
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
Building Functions
Building FunctionsBuilding Functions
Building Functions
 
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Monad and Algebraic Design in Functional Programming
Monad and Algebraic Design in Functional ProgrammingMonad and Algebraic Design in Functional Programming
Monad and Algebraic Design in Functional Programming
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystified
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1
 
Monad presentation scala as a category
Monad presentation   scala as a categoryMonad presentation   scala as a category
Monad presentation scala as a category
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
 
Composition birds-and-recursion
Composition birds-and-recursionComposition birds-and-recursion
Composition birds-and-recursion
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain Models
 

Recently uploaded

Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
lorraineandreiamcidl
 
Codeigniter VS Cakephp Which is Better for Web Development.pdf
Codeigniter VS Cakephp Which is Better for Web Development.pdfCodeigniter VS Cakephp Which is Better for Web Development.pdf
Codeigniter VS Cakephp Which is Better for Web Development.pdf
Semiosis Software Private Limited
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
Preparing Non - Technical Founders for Engaging a Tech Agency
Preparing Non - Technical Founders for Engaging  a  Tech AgencyPreparing Non - Technical Founders for Engaging  a  Tech Agency
Preparing Non - Technical Founders for Engaging a Tech Agency
ISH Technologies
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 

Recently uploaded (20)

Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
 
Codeigniter VS Cakephp Which is Better for Web Development.pdf
Codeigniter VS Cakephp Which is Better for Web Development.pdfCodeigniter VS Cakephp Which is Better for Web Development.pdf
Codeigniter VS Cakephp Which is Better for Web Development.pdf
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
Preparing Non - Technical Founders for Engaging a Tech Agency
Preparing Non - Technical Founders for Engaging  a  Tech AgencyPreparing Non - Technical Founders for Engaging  a  Tech Agency
Preparing Non - Technical Founders for Engaging a Tech Agency
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 

Essence of the iterator pattern

  • 2. Goal “Imperative iterations using the pattern have two simultaneous aspects: mapping and accumulating.” Jeremy Gibbons & Bruno C. d. S. Oliveira Markus Klink, @joheinz, markus.klink@inoio.de
  • 3. Functionalmappingand accumulating trait Traverse[F[_]] extends Functor[F] with Foldable[F] { def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]] } trait Applicative[F[_]] extends Functor[F] { def ap[A,B](fa: F[A])(f: F[A => B]) : F[B] def pure(a: A) : F[A] def map[A,B](fa: F[A])(f: A => B) : F[B] = ap(fa)(pure(f)) } Traverse takes a structure F[A], injects each element via the function f: A => G[B] into an Applicative G[_] and combines the results into G[F[B] using the applicative instance of G. Markus Klink, @joheinz, markus.klink@inoio.de
  • 4. Acloser look trait Foldable[F[_]] { def foldRight[A, B](fa: F[A], z: => B)(f: (A, B) => B): B } trait Traverse[F[_]] extends Functor[F] with Foldable[F] { def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]] } Look at the similarities! Markus Klink, @joheinz, markus.klink@inoio.de
  • 5. Traversing is "almost" like Folding: » Look! No zero element: def foldRight[A, B](fa: F[A], z: => B)(f: (A, B) => B): B def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]] » Look! B is wrapped in an Applicative and our F: def foldRight[A, B](fa: F[A], z: => B)(f: (A, B) => B): B def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]] Markus Klink, @joheinz, markus.klink@inoio.de
  • 6. Accumulating Markus Klink, @joheinz, markus.klink@inoio.de
  • 7. val l = List(1,2,3) val result: Future[List[String]] = l.traverse(a => Future.successful { a.toString }) How? // traverse implementation of List, G[_] is the future override def traverse[G[_]: Applicative, A, B](fa: List[A])(f: (A) => G[B]): G[List[B]] = { val emptyListInG: G[List[B]] = Applicative[G].pure(List.empty[B]) // if the list is empty we need a Future { List.empty() } // f(a) gives us another G[B], which we can inject into B => B => Future[List[B]] foldRight(fa, emptyListInG) { (a: A, fbs: G[List[B]]) => Applicative[G].apply2(f(a), fbs)(_ +: _) } } // applicative instance of Future, example... override def ap[A,B](F: => Future[A])(f: => Future[A => B]) : Future[B] = { for { a <- F g <- f } yield { g(a) } } Markus Klink, @joheinz, markus.klink@inoio.de
  • 8. Gibbons & Oliveiraclaimthatwe can do: val x : List[Char]= "1234".toList val result : Int = x.traverse(c => ???) assert(4 == result) The claim is that we can accumulate values, or write the length function just with Traverse/Applicative Markus Klink, @joheinz, markus.klink@inoio.de
  • 9. How? » we need a result type G[List[Int]] which equals Int » G needs to be an applicative » we need to calculate a sum of all the values. » we need a zero value in case the list is empty, because of ... val emptyListInG: G[List[B]] = Applicative[G].pure(List.empty[B]) Markus Klink, @joheinz, markus.klink@inoio.de
  • 10. Each Monoid gives risetoan applicative trait Monoid[F] extends Semigroup[F] { self => /** * the identity element. */ def zero: F def applicative: Applicative[Lambda[a => F]] = new Applicative[Lambda[a => F]] { // mapping just returns ourselves override def map[A, B](fa: F)(f: A => B) : F = fa // putting any value into this Applicative will put the Monoid.zero in it def pure[A](a: => A): F = self.zero // Applying this Applicative combines each value with the append function. def ap[A, B](fa: => F)(f: => F): F = self.append(f, fa) } Markus Klink, @joheinz, markus.klink@inoio.de
  • 11. How2 Part of the trick is this type: Applicative[Lambda[a => F]]! It means that we throw everything away and create a type G[_] which behaves like F. So... val x : List[Char]= "1234".toList val charCounter : Applicative[Lambda[a => Int]] = Monoid[Int].applicative // we just "reversed" the parameters of traverse // the summing is done automatically via append charCounter.traverse(x)(_ => 1) Markus Klink, @joheinz, markus.klink@inoio.de
  • 12. Counting lines In the previous example we assigned each char in the list to a 1 and let the Monoid do the work. val x : List[Char] = "1233n1234n" val lineCounter : Applicative[Lambda[a => Int]] = Monoid[Int].applicative lineCounter.traverse(x){c => if (c == 'n') 1 else 0 } Markus Klink, @joheinz, markus.klink@inoio.de
  • 13. Products ofApplicatives Doing bothatthe sametimewithinasingle traversal val x : List[Char]= "1234n1234n" val counter : Applicative[Lambda[a => Int]] = Monoid[Int].applicative val charLineApp : Applicative[Lambda[a => (Int, Int)]] = counter.product[Lambda[a => Int](counter) val (chars, lines) = counter.traverse(x){c => (1 -> if (c == 'n') 1 else 0 } Markus Klink, @joheinz, markus.klink@inoio.de
  • 14. Countingwords Counting words cannot work on the current position alone. We need to track changes from spaces to non spaces to recognize the beginning of a new word. def atWordStart(c: Char): State[Boolean, Int] = State { (prev: Boolean) => val cur = c != ' ' (cur, if (!prev && cur) 1 else 0) } val WordCount : Applicative[Lambda[a => Int]] = State.stateMonad[Boolean].compose[Lambda[a => Int](counter) val StateWordCount = WordCount.traverse(text)(c => atWordStart(c)) StateWordCount.eval(false) Markus Klink, @joheinz, markus.klink@inoio.de
  • 15. Usingthe productofall3 countersto implementwc val AppCharLinesWord: Applicative[Lambda[a => ((Int, Int), State[Boolean, Int])]] = Count // char count .product[Lambda[a => Int]](Count) // line count .product[Lambda[a => State[Boolean, Int]]](WordCount) // word count val ((charCount, lineCount), wordCountState) = AppCharLinesWord.traverse(text)((c: Char) => ((1, if (c == 'n') 1 else 0), atWordStart(c))) val wordCount: Int = wordCountState.eval(false) Markus Klink, @joheinz, markus.klink@inoio.de
  • 16. Collecting some state and modifying elements Markus Klink, @joheinz, markus.klink@inoio.de
  • 17. // start value public Integer count = 0; public Collection<Person> collection = ...; for (e <- collection) { // or we use an if count = count + 1; // side effecting function // or we map into another collection e.modify(); } Obviously in a functional programming language, we would not want to modify the collection but get back a new collection. We also would like to get the (stateful) counter back. Markus Klink, @joheinz, markus.klink@inoio.de
  • 18. def collect[G[_]: Applicative, A, B](fa: F[A])(f: A => G[Unit])(g: A => B): G[F[B]] = { val G = implicitly[Applicative[G]] val applicationFn : A => G[B] = a => G.ap(f(a))(G.pure((u: Unit) => g(a))) self.traverse(fa)(applicationFn) } def collectS[S, A, B](fa: F[A])(f: A => State[S, Unit])(g: A => B): State[S, F[B]] = { collect[Lambda[a => State[S, a]], A, B](fa)(f)(g) } val list : List[Person] = ... val stateMonad = State.stateMonad[Int] val (counter, updatedList) = list.collectS{ a => for { count <- get; _ <- put(count + 1) } yield ()}(p => p.modify()).run(0) Markus Klink, @joheinz, markus.klink@inoio.de
  • 19. Modifying elements depending on some state Markus Klink, @joheinz, markus.klink@inoio.de
  • 20. // start value public Collection<Person> collection = ...; for (e <- collection) { e.modify(stateful()); } Now the modification depends on some state we are collecting. Markus Klink, @joheinz, markus.klink@inoio.de
  • 21. def disperse[G[_]: Applicative, A, B, C](fa: F[A])(fb: G[B], g: A => B => C): G[F[C]] = { val G = implicitly[Applicative[G]] val applicationFn: A => G[C] = a => G.ap(fb)(G.pure(g(a))) self.traverse(fa)(applicationFn) } def disperseS[S, A, C](fa: F[A])(fb: State[S, S], g: A => S => C) : State[S,F[C]] = { disperse[Lambda[a => State[S, a]], A, S, C](fa)(fb, g) } Markus Klink, @joheinz, markus.klink@inoio.de
  • 22. THANKS Markus Klink, @joheinz, markus.klink@inoio.de