SlideShare a Scribd company logo
Computation        Functor


APPLICATIVE        For loop
        Traverse
Computation

              K[T]
A type of            A type of value
computation
Computations
Zero or one    Option[T]
Zero or more   List[T]
Later          Future[T]
Depend on S    State[S, T]
Ext. effects   IO[T]
Create computations?

Option[T]     Some(t)

List[T]       List(t)

Future[T]     future(t)

State[S, T]   state(s => (s, t))

IO[T]         IO(t)
Pointed

         K[T].point(t)

Compute a value
Use computations?

Option[T]     Some(2)

List[T]       List(1, 2)

Future[T]     future(calculate)

State[S, T]   state(s => (s, s+1))

IO[T]         IO(println(“hello”))
Functor

K[T] map f

           Use the value
Functors map

Option[T]     modify the value

List[T]       modify the values

Future[T]     modify later

State[S, T]   modify ts

IO[T]         modify the action
Applicative
Before
getUser(props: Properties): String
getPassword(props: Properties): String

getConnection(user: String, pw: String):
Connection = {
  if (user != null && pw != null)
    ....
}

getConnection(getUser(p), getPassword(p))
Applicative
After
getUser(props: Properties): Option[String]
getPassword(props: Properties): Option[String]

getConnection(user: String, pw: String):
Connection = {
  if (user != null && pw != null)
    ....
}


getConnection(?, ?)
Applicative

f(a, b)
How?

f(K[a], K[b])
Use Pointed

f(a:A, b:B): C
point

fk: K[A => B => C]
Applicative

    K[A => B] <*> K[A]
            ==
           K[B]
Apply the function
Applicative
    K[A => B => C] <*>
    K[A]           <*> K[B]
                ==
         K[B => C] <*> K[B]
                 ==

Currying ftw!
                K[C]
Applicative

K(f) <*> K(a) <*> K(b)



Apply ‘f’ to ‘a’ and ‘b’ “inside” ‘K’
Applicative

K(f) <*> K(a) <*> K(b)



Apply ‘f’ to ‘a’ and ‘b’ “inside” ‘K’
Applicative
           Option

Some(getConnection.curried) <*>
user(p)                     <*>
password(p)
Applicative
            Option

(user(p) <**> password(p))(mkConnection)

mkConnection <$> user(p) <*> password(p)
Applicative
           Future

future(discount(_,_))) <*>
future(amount)         <*>
future(rate)

: Future[Double]
Applicative
             List
List(plus1) <*> List(1, 2, 3)




List(2, 3, 4)
Applicative
             List

List(plus1, plus2) <*> List(1, 2, 3)



== List(2, 3, 4, 3, 4, 5)

ratings <*> clients
Applicative
            ZipList

List(plus1, plus2, plus3) <*>

List(1,     2,     3)


== List(1, 4, 6)
Applicative State
val add     = (i: Int) => (j: Int) => i+j
val times   = (i: Int) => (j: Int) => i*j

// 0 -> 1, 2, 3, 4
val s1     = modify((i: Int) => i+1)



(add     <$> s1 <*> s1)(1) == ?
(times   <$> s1 <*> s1)(1) == ?
Applicative State
                             current state
            +1=2   +1=3
(add     <$> s1 <*> s1)(1) == (3, 5)

                           add 2 previous states
            +1=2   +1=3
(times   <$> s1 <*> s1)(1) == (3, 6)

                          multiply 2 previous states
Monad, remember?
Unit
def unit[A](a: =>A): M[A]



Bind
def bind[A, B](ma: M[A])(f: A => M[B]): M[B]
Monad => Applicative
Point
def point(a: =>A) = Monad[M].unit(a)

Apply
def <*>[A, B](mf: M[A=>B])(ma: M[A]):M[B] =
  Monad[M].bind(mf) { f =>
    Monad[M].bind(ma) { a =>
      f(a) // M[B]
    } // M[B]
  } // M[B]
The “for” loop
val basket = Basket(orange, apple)
var count = 0

val juices = Basket[Juice]()
                                 accumulation
for (fruit <- basket) {
  count = count + 1
  juices.add(fruit.press)              “mapping”
}

 same container for the result
Traverse

                        Traversable
def traverse(f: A => F[B]): T[A] => F[T[B]]


                Applicative             Same
                                      structure
Traverse a List

List(x, y, z): List[A]

f: A => F[B]
Traverse a List
       Apply ‘f’ to ‘z’



F(::) <*> F(z) <*> F(Nil)

“Rebuild” the list


 F(z :: Nil)
Traverse a List

F(::) <*> F(y) <*> F(z :: Nil)

 F(y :: z :: Nil)

F(::) <*> F(x) <*> F(y::z::Nil)

 F(x :: y :: z :: Nil)
Traverse a
            Binary Tree
    f
                x
                    y       z
x
                                x
        y   z   y       z
                                    y   z
`sequence`

def sequence[F: Applicative]:
  T[F[A]] => F[T[A]] =

   traverse(identity)
`sequence`
Execute concurrently?
val examples: Seq[Example] =
  Seq(e1, e2, e3)
                         Sequence of promises
val executing: Seq[Promise[Result]] =
  examples.map(e => promise(e.execute))

val results: Promise[Seq[Result]] =
  executing.sequence

                        Promise of a sequence
Measure with
              Monoids
trait Monoid[A] {
  val zero: A; def append(a: A, b: A): A
}

def measure[T: Traversable, M : Monoid]
  (f: A => M): T[A] => M


Count elements:        Int Monoid
Accumulate elements:   List Monoid
`measure`

def measure[T: Traversable, M : Monoid]
  (f: A => M) =

 traverse(a => f(a))
`Const`
                  “Phantom “ type
case class Const[M, +A](value: M)

new Applicative[Const[M, *]] {
  def point(a: =>A) = Const(Monoid[M].zero)

    def <*>(f: Const[M, A=>B], a: Const[M, A]) =
      Const(Monoid[M].append(f.value, a.value))
}
Applicative => Monad

Unit
def unit[A](a: =>A) = Const(Monoid[M].zero)


Bind
def bind[A, B](ma: Const[M, A])
              (f: A => Const[M, B]) =
=> but no value `a: A` to be found!
`measure`
Sum up all sizes
def sumSizes[A : Size](seq: Seq[A]) =
  measure(a => Size[A].size(a))(seq)


Collect all sizes
def collectSizes[A : Size](seq: Seq[A]) =
  measure(a => List(Size[A].size(a)))(seq)
`contents`
def contents[A](tree: Tree[A]): List[A] =
  measure(a => List(a))(tree)




   x
                     =>        List(x, y, z)

       y     z
`shape`
def shape[A](tree: Tree[A]): Tree[Unit] =
  map(a => ())(tree)




   x
                     =>        .

       y     z                      .       .


def map[A, B](f: A => B): T[A] =>
  traverse(a => Ident(f(a)))

                                Identity monad
`decompose`
def decompose[A](tree: Tree[A]) =
  (contents(tree), shape(tree))


                               List(x, y, z)

   x
                     =>
       y     z                 .

                                    .     .



                              Not very efficient…
Applicative products
case class Product[F1[_], F2[_], A](
  first: F1[A], second: F2[A])


F1: Applicative, F2: Applicative
def point[A, B](a: => A) =
  Product[F1, F2, B](Pointed[F1].point(a),
                     Pointed[F2].point(a))

def <*>[A, B](f: Product[F1, F2, A => B]) =
  (c: Product[F1, F2, A]) =>
      Product[F1, F2, B](f.first <*> c.first,
                         f.second <*> c.second)
`contents               ⊗   shape`
F1 = Const[List[A], *]
F2 = Ident[*]
val contents = (a: A) => Const[List[A], Unit](List(a))
val shape    = (a: A) => Ident(())

val contentsAndShape:
  A => Product[Const[List[A], _], Ident[_], *] =
    contents ⊗ shape


tree.traverse(contentsAndShape)
Type indifference 
One parameter type constructor
trait Apply[F[_]] {
  def <*>[A, B](f: F[A => B]): F[A] => F[B]
}



List[Int]: Monoid Applicative => Const[List[Int], _]
({type l[a]=Const[List[Int], a]})#l
Type indifference 
Anonymous type
 ({type l[a]=Const[List[Int], a]})#l
Type member
({type l[a]=Const[List[Int], a]})#l
Type projection
({type l[a]=Const[List[Int], a]})#l
type ApplicativeProduct =
({type l[a]=Product[Const[List[A],_],Ident[_],a]})#l
Type indifference 
Measure
def measure[M : Monoid](f: T => M): M =
  traverse(t => Monoid[M].unit(f(t))).value


For real…
def measure[M : Monoid](f: A => M): M =
 traverse[(type l[a]=Const[M, a]})#l, A, Any] { t =>
   Monoid[M].point(f(t))
 }.value
`collect`
Accumulate and map
def collect[F[_] : Applicative, A, B]
  (f: A => F[Unit], g: A => B) = {

    traverse { a: A =>
      Applicative[F].point((u: Unit) => g(a)) <*> f(a))
    }
}

val count = (i: Int) => state((n: Int) => (n+1, ()))
val map   = (i: Int) => i.toString

tree.collect(count, map).apply(0)
  (2, Bin(Leaf("1"), Leaf("2")))
`disperse`
Label and map
def disperse(F[_] : Applicative, A, B, C]
  (f: F[B], g: A => B => C): T[A] => F[T[C]]


val tree = Bin(Leaf(1.1), Bin(Leaf(2.2), Leaf(3.3)))

val label = modify((n:Int) => n+1)
val name = (p1:Double) => (p2:Int) => p1+" node is "+p2

tree.disperse(label, name).apply(0)._2

 Bin(Leaf("1.1 node is 1"),
      Bin(Leaf("2.2 node is 2"), Leaf("3.3 node is 3")))
EIP `measure`
Map and count
def measure[F[_] : Applicative, A, B]
  (f: F[B], g: A => C): T[A] => F[C]



val crosses = modify((s: String) => s+"x")
val map     = (i: Int) => i.toString

tree.measure(crosses, map).apply("")
("xxx", Bin(Leaf("1"), Bin(Leaf("2"),
                             Leaf("3"))))
Traversals

                                           mapped depend state depend on
   function   map element   create state
                                              on state       element

collect           X              X                              X
disperse          X              X               X
measure           X              X
traverse          X              X               X              X
reduce                           X                              X
reduceConst                      X
map               X
Quizz
def findMatches(divs: Seq[Int], nums: Seq[Int])


findMatches(Seq(2, 3, 4), Seq(1, 6, 7, 8, 9))
=> Seq((2, 6), (3, 9), (4, 8))


With Traverse?
Quizz
def findMatches(divs: Seq[Int], nums: Seq[Int]) = {

    case class S(matches: Seq[(Int, Int)] = Seq[(Int, Int)](),
                 remaining: Seq[Int])

    val initialState = S(remaining = nums)

    def find(div: Int) = modify { (s: S) =>
      s.remaining.find(_ % div == 0).map { (n: Int) =>
        S(s.matches :+ div -> n, s.remaining - n)
      }.getOrElse(s)
    }

    divs.traverse(find).exec(initialState).matches
}
Composition
val results = new ListBuffer

for (a <- as) {
  val currentSize = a.size
  total += currentSize
  results.add(total)
}

F1 (map) then F2 (sum)
     F2 [F1[_]] => Applicative?
`assemble`
Shape + content => assembled
def assemble[F[_] : Applicative, A]:
  (f: F[Unit], g: List[A]): T[A] => F[A]

val shape: BinaryTree[Unit] = Bin(Leaf(()), Leaf(()))

shape.assemble(List(1, 2))
 (List(), Some(Bin(Leaf(1), Leaf(2))))

shape.assemble(List(1, 2, 3))
 (List(3), Some(Bin(Leaf(1), Leaf(2))))

shape.assemble(List(1))
 (List(), None)
`assemble`
def takeHead: State[List[B], Option[B]] =
  state { s: List[B] =>
    s match {
      case Nil     => (Nil, None)
      case x :: xs => (xs, Some(x))
    }
  }


 F1: Option[_]                  An element to insert

F2 :State[List[A], _]           the rest of the list

F2 [F1]: State[List[A], Option[_]]     An applicative
`assemble`
def assemble[F[_] : Applicative, A]
  (f: F[Unit], list: List[A]) =

 traverse(takeHead).apply(list)
Monadic composition
M : Monad
val f: B => M[C]
val g: A => M[B]

val h: A => M[C] = f   • g


Fusion?
traverse(f) • traverse(g) == traverse(f • g)
Monadic composition
Yes if the Monad is commutative
 val xy = for {                   val yx = for {
   x <- (mx: M[X])                  y <- (my: M[Y])
                      xy == yx
   y <- (my: M[Y])                  x <- (mx: M[X])
 } yield (x, y)                   } yield (x, y)



State is *not* commutative
val mx = state((n: Int) => (n+1, n+1))
val my = state((n: Int) => (n+1, n+1))
xy.apply(0) == (2, (1, 2))
yx.apply(0) == (2, (2, 1))
Applicative composition vs
       Monadic composition
Not commutative functions => fusion
Seq(1,2,3).traverse(times2 ⊙ plus1) == 4
 State[Int, State[Int, Seq[Int]]]


Seq(1,2,3).traverse(times2) ⊙
Seq(1,2,3).traverse(plus1) == 4
 State[Int, Seq[State[Int, Int]]
Monadic composition:
            conjecture
Commutative functions
val plus1 = (a: A) => state((n: Int) => (n+1, a))
val plus2 = (a: A) => state((n: Int) => (n+2, a))
val times2 = (a: A) => state((n: Int) => (n*2, a))

plus1 and plus2 are commutative
plus1 and times2 are not commutative:

(0 + 1) * 2 != (0 * 2) + 1
Monadic composition:
             conjecture
 Commutative functions => fusion
Seq(1,2,3).traverse(plus2 ∎ plus1) == 10
Seq(1,2,3).traverse(plus2) ∎
  Seq(1,2,3).traverse(plus1) == 10



 Not commutative functions => no fusion
Seq(1,2,3).traverse(times2 ∎ plus1) == 22
Seq(1,2,3).traverse(times2) ∎
  Seq(1,2,3).traverse(plus1) == 32

More Related Content

What's hot

Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov VyacheslavSeminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Vyacheslav Arbuzov
 
Programs in array using SWIFT
Programs in array using SWIFTPrograms in array using SWIFT
Programs in array using SWIFT
vikram mahendra
 
Perm winter school 2014.01.31
Perm winter school 2014.01.31Perm winter school 2014.01.31
Perm winter school 2014.01.31
Vyacheslav Arbuzov
 
02 arrays
02 arrays02 arrays
02 arrays
Rajan Gautam
 
Data import-cheatsheet
Data import-cheatsheetData import-cheatsheet
Data import-cheatsheet
Dieudonne Nahigombeye
 
Seminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mmeSeminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mme
Vyacheslav Arbuzov
 
20090622 Bp Study#22
20090622 Bp Study#2220090622 Bp Study#22
20090622 Bp Study#22
Tomohito Ozaki
 
하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3
Kwang Yul Seo
 
Python object oriented programming (lab2) (2)
Python object oriented programming (lab2) (2)Python object oriented programming (lab2) (2)
Python object oriented programming (lab2) (2)
iloveallahsomuch
 
Seminar psu 20.10.2013
Seminar psu 20.10.2013Seminar psu 20.10.2013
Seminar psu 20.10.2013
Vyacheslav Arbuzov
 
Send + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSPSend + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSP
Filippo Vitale
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4
Kwang Yul Seo
 
TensorFlow in Practice
TensorFlow in PracticeTensorFlow in Practice
TensorFlow in Practice
indico data
 
Gentlest Introduction to Tensorflow - Part 2
Gentlest Introduction to Tensorflow - Part 2Gentlest Introduction to Tensorflow - Part 2
Gentlest Introduction to Tensorflow - Part 2
Khor SoonHin
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
stasimus
 
Matlab plotting
Matlab plottingMatlab plotting
Matlab plotting
shahid sultan
 
Matlab plotting
Matlab plottingMatlab plotting
Matlab plotting
pramodkumar1804
 
The Ring programming language version 1.5.4 book - Part 22 of 185
The Ring programming language version 1.5.4 book - Part 22 of 185The Ring programming language version 1.5.4 book - Part 22 of 185
The Ring programming language version 1.5.4 book - Part 22 of 185
Mahmoud Samir Fayed
 
My sql cheat sheet
My sql cheat sheetMy sql cheat sheet
My sql cheat sheet
Piyush Mittal
 
Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015
Filippo Vitale
 

What's hot (20)

Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov VyacheslavSeminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
 
Programs in array using SWIFT
Programs in array using SWIFTPrograms in array using SWIFT
Programs in array using SWIFT
 
Perm winter school 2014.01.31
Perm winter school 2014.01.31Perm winter school 2014.01.31
Perm winter school 2014.01.31
 
02 arrays
02 arrays02 arrays
02 arrays
 
Data import-cheatsheet
Data import-cheatsheetData import-cheatsheet
Data import-cheatsheet
 
Seminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mmeSeminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mme
 
20090622 Bp Study#22
20090622 Bp Study#2220090622 Bp Study#22
20090622 Bp Study#22
 
하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3
 
Python object oriented programming (lab2) (2)
Python object oriented programming (lab2) (2)Python object oriented programming (lab2) (2)
Python object oriented programming (lab2) (2)
 
Seminar psu 20.10.2013
Seminar psu 20.10.2013Seminar psu 20.10.2013
Seminar psu 20.10.2013
 
Send + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSPSend + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSP
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4
 
TensorFlow in Practice
TensorFlow in PracticeTensorFlow in Practice
TensorFlow in Practice
 
Gentlest Introduction to Tensorflow - Part 2
Gentlest Introduction to Tensorflow - Part 2Gentlest Introduction to Tensorflow - Part 2
Gentlest Introduction to Tensorflow - Part 2
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
Matlab plotting
Matlab plottingMatlab plotting
Matlab plotting
 
Matlab plotting
Matlab plottingMatlab plotting
Matlab plotting
 
The Ring programming language version 1.5.4 book - Part 22 of 185
The Ring programming language version 1.5.4 book - Part 22 of 185The Ring programming language version 1.5.4 book - Part 22 of 185
The Ring programming language version 1.5.4 book - Part 22 of 185
 
My sql cheat sheet
My sql cheat sheetMy sql cheat sheet
My sql cheat sheet
 
Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015
 

Viewers also liked

Welcome To The Marketing Pod
Welcome To The Marketing PodWelcome To The Marketing Pod
Welcome To The Marketing Pod
TheMarketingPod
 
Specs2 - Scala-Syd presentation
Specs2 - Scala-Syd presentationSpecs2 - Scala-Syd presentation
Specs2 - Scala-Syd presentation
Eric Torreborre
 
Bohemians
Bohemians Bohemians
Bohemians
trupti kambli
 
Strong functional programming
Strong functional programmingStrong functional programming
Strong functional programming
Eric Torreborre
 
DSLs with fold algebras
DSLs with fold algebrasDSLs with fold algebras
DSLs with fold algebras
Eric Torreborre
 
Specs2 whirlwind tour at Scaladays 2014
Specs2 whirlwind tour at Scaladays 2014Specs2 whirlwind tour at Scaladays 2014
Specs2 whirlwind tour at Scaladays 2014
Eric Torreborre
 

Viewers also liked (6)

Welcome To The Marketing Pod
Welcome To The Marketing PodWelcome To The Marketing Pod
Welcome To The Marketing Pod
 
Specs2 - Scala-Syd presentation
Specs2 - Scala-Syd presentationSpecs2 - Scala-Syd presentation
Specs2 - Scala-Syd presentation
 
Bohemians
Bohemians Bohemians
Bohemians
 
Strong functional programming
Strong functional programmingStrong functional programming
Strong functional programming
 
DSLs with fold algebras
DSLs with fold algebrasDSLs with fold algebras
DSLs with fold algebras
 
Specs2 whirlwind tour at Scaladays 2014
Specs2 whirlwind tour at Scaladays 2014Specs2 whirlwind tour at Scaladays 2014
Specs2 whirlwind tour at Scaladays 2014
 

Similar to The Essence of the Iterator Pattern (pdf)

Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
Hang Zhao
 
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
 
Thesis PPT
Thesis PPTThesis PPT
Thesis PPT
Drew Ferkin
 
Thesis
ThesisThesis
Thesis
Drew Ferkin
 
Functional programming in scala
Functional programming in scalaFunctional programming in scala
Functional programming in scala
Siarhiej Siemianchuk
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystified
Alessandro Lacava
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
league
 
Monadologie
MonadologieMonadologie
Monadologie
league
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
Raymond Roestenburg
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
Hang Zhao
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monads
kenbot
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aid
David Hoyt
 
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
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
Philip Schwarz
 
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
 
purrr.pdf
purrr.pdfpurrr.pdf
purrr.pdf
Mateus S. Xavier
 
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
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
Debasish Ghosh
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
Alexander Zaidel
 
Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...
Philip Schwarz
 

Similar to The Essence of the Iterator Pattern (pdf) (20)

Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
 
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
 
Thesis PPT
Thesis PPTThesis PPT
Thesis PPT
 
Thesis
ThesisThesis
Thesis
 
Functional programming in scala
Functional programming in scalaFunctional programming in scala
Functional programming in scala
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystified
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
Monadologie
MonadologieMonadologie
Monadologie
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monads
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aid
 
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
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
 
purrr.pdf
purrr.pdfpurrr.pdf
purrr.pdf
 
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
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...
 

More from Eric Torreborre

wire-all-the-things-lambda-days-2023.pdf
wire-all-the-things-lambda-days-2023.pdfwire-all-the-things-lambda-days-2023.pdf
wire-all-the-things-lambda-days-2023.pdf
Eric Torreborre
 
The many faces of modularity
The many faces of modularityThe many faces of modularity
The many faces of modularity
Eric Torreborre
 
What haskell taught us when we were not looking
What haskell taught us when we were not lookingWhat haskell taught us when we were not looking
What haskell taught us when we were not looking
Eric Torreborre
 
Wire once, rewire twice! (Haskell exchange-2018)
Wire once, rewire twice! (Haskell exchange-2018)Wire once, rewire twice! (Haskell exchange-2018)
Wire once, rewire twice! (Haskell exchange-2018)
Eric Torreborre
 
Pratical eff-functional-conf
Pratical eff-functional-confPratical eff-functional-conf
Pratical eff-functional-conf
Eric Torreborre
 
Specs2, from starters to dessert and... a look in the kitchen
Specs2, from starters to dessert and... a look in the kitchenSpecs2, from starters to dessert and... a look in the kitchen
Specs2, from starters to dessert and... a look in the kitchen
Eric Torreborre
 
Streaming, effects and beautiful folds: a winning trilogy
Streaming, effects and beautiful folds: a winning trilogyStreaming, effects and beautiful folds: a winning trilogy
Streaming, effects and beautiful folds: a winning trilogy
Eric Torreborre
 
Pratical eff-scalaitaly-2017
Pratical eff-scalaitaly-2017Pratical eff-scalaitaly-2017
Pratical eff-scalaitaly-2017
Eric Torreborre
 
Pratical eff monad at Scaladays Chicago
Pratical eff monad at Scaladays ChicagoPratical eff monad at Scaladays Chicago
Pratical eff monad at Scaladays Chicago
Eric Torreborre
 
Pratical eff
Pratical effPratical eff
Pratical eff
Eric Torreborre
 
The Eff monad, one monad to rule them all
The Eff monad, one monad to rule them allThe Eff monad, one monad to rule them all
The Eff monad, one monad to rule them all
Eric Torreborre
 
Easy di-slideshare
Easy di-slideshareEasy di-slideshare
Easy di-slideshare
Eric Torreborre
 
Data generation, the hard parts
Data generation, the hard partsData generation, the hard parts
Data generation, the hard parts
Eric Torreborre
 
Origami, a monadic fold library for Scala
Origami, a monadic fold library for ScalaOrigami, a monadic fold library for Scala
Origami, a monadic fold library for Scala
Eric Torreborre
 
Datatypes for the real world
Datatypes for the real worldDatatypes for the real world
Datatypes for the real world
Eric Torreborre
 
Specs2 3.4
Specs2 3.4Specs2 3.4
Specs2 3.4
Eric Torreborre
 
Epic success \/ failure, refactoring to *real* FP
Epic success \/ failure, refactoring to *real* FPEpic success \/ failure, refactoring to *real* FP
Epic success \/ failure, refactoring to *real* FP
Eric Torreborre
 
Vampire methods
Vampire methodsVampire methods
Vampire methods
Eric Torreborre
 
Specs2 whirlwind-tour
Specs2 whirlwind-tourSpecs2 whirlwind-tour
Specs2 whirlwind-tour
Eric Torreborre
 
Scala days2013 proxyfactorybeandelegate
Scala days2013 proxyfactorybeandelegate Scala days2013 proxyfactorybeandelegate
Scala days2013 proxyfactorybeandelegate
Eric Torreborre
 

More from Eric Torreborre (20)

wire-all-the-things-lambda-days-2023.pdf
wire-all-the-things-lambda-days-2023.pdfwire-all-the-things-lambda-days-2023.pdf
wire-all-the-things-lambda-days-2023.pdf
 
The many faces of modularity
The many faces of modularityThe many faces of modularity
The many faces of modularity
 
What haskell taught us when we were not looking
What haskell taught us when we were not lookingWhat haskell taught us when we were not looking
What haskell taught us when we were not looking
 
Wire once, rewire twice! (Haskell exchange-2018)
Wire once, rewire twice! (Haskell exchange-2018)Wire once, rewire twice! (Haskell exchange-2018)
Wire once, rewire twice! (Haskell exchange-2018)
 
Pratical eff-functional-conf
Pratical eff-functional-confPratical eff-functional-conf
Pratical eff-functional-conf
 
Specs2, from starters to dessert and... a look in the kitchen
Specs2, from starters to dessert and... a look in the kitchenSpecs2, from starters to dessert and... a look in the kitchen
Specs2, from starters to dessert and... a look in the kitchen
 
Streaming, effects and beautiful folds: a winning trilogy
Streaming, effects and beautiful folds: a winning trilogyStreaming, effects and beautiful folds: a winning trilogy
Streaming, effects and beautiful folds: a winning trilogy
 
Pratical eff-scalaitaly-2017
Pratical eff-scalaitaly-2017Pratical eff-scalaitaly-2017
Pratical eff-scalaitaly-2017
 
Pratical eff monad at Scaladays Chicago
Pratical eff monad at Scaladays ChicagoPratical eff monad at Scaladays Chicago
Pratical eff monad at Scaladays Chicago
 
Pratical eff
Pratical effPratical eff
Pratical eff
 
The Eff monad, one monad to rule them all
The Eff monad, one monad to rule them allThe Eff monad, one monad to rule them all
The Eff monad, one monad to rule them all
 
Easy di-slideshare
Easy di-slideshareEasy di-slideshare
Easy di-slideshare
 
Data generation, the hard parts
Data generation, the hard partsData generation, the hard parts
Data generation, the hard parts
 
Origami, a monadic fold library for Scala
Origami, a monadic fold library for ScalaOrigami, a monadic fold library for Scala
Origami, a monadic fold library for Scala
 
Datatypes for the real world
Datatypes for the real worldDatatypes for the real world
Datatypes for the real world
 
Specs2 3.4
Specs2 3.4Specs2 3.4
Specs2 3.4
 
Epic success \/ failure, refactoring to *real* FP
Epic success \/ failure, refactoring to *real* FPEpic success \/ failure, refactoring to *real* FP
Epic success \/ failure, refactoring to *real* FP
 
Vampire methods
Vampire methodsVampire methods
Vampire methods
 
Specs2 whirlwind-tour
Specs2 whirlwind-tourSpecs2 whirlwind-tour
Specs2 whirlwind-tour
 
Scala days2013 proxyfactorybeandelegate
Scala days2013 proxyfactorybeandelegate Scala days2013 proxyfactorybeandelegate
Scala days2013 proxyfactorybeandelegate
 

Recently uploaded

HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
Essentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation ParametersEssentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation Parameters
Safe Software
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
Pablo Gómez Abajo
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Apps Break Data
Apps Break DataApps Break Data
Apps Break Data
Ivo Velitchkov
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectorsConnector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
DianaGray10
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
Miro Wengner
 
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge GraphGraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
Neo4j
 
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
Edge AI and Vision Alliance
 
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and BioinformaticiansBiomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Neo4j
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
Ajin Abraham
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
ScyllaDB
 
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid ResearchHarnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Neo4j
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
Fwdays
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
DianaGray10
 

Recently uploaded (20)

HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
Essentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation ParametersEssentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation Parameters
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Apps Break Data
Apps Break DataApps Break Data
Apps Break Data
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectorsConnector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
 
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge GraphGraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
 
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
 
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and BioinformaticiansBiomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
 
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid ResearchHarnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
 

The Essence of the Iterator Pattern (pdf)

  • 1.
  • 2. Computation Functor APPLICATIVE For loop Traverse
  • 3. Computation K[T] A type of A type of value computation
  • 4. Computations Zero or one Option[T] Zero or more List[T] Later Future[T] Depend on S State[S, T] Ext. effects IO[T]
  • 5. Create computations? Option[T] Some(t) List[T] List(t) Future[T] future(t) State[S, T] state(s => (s, t)) IO[T] IO(t)
  • 6. Pointed K[T].point(t) Compute a value
  • 7. Use computations? Option[T] Some(2) List[T] List(1, 2) Future[T] future(calculate) State[S, T] state(s => (s, s+1)) IO[T] IO(println(“hello”))
  • 8. Functor K[T] map f Use the value
  • 9. Functors map Option[T] modify the value List[T] modify the values Future[T] modify later State[S, T] modify ts IO[T] modify the action
  • 10. Applicative Before getUser(props: Properties): String getPassword(props: Properties): String getConnection(user: String, pw: String): Connection = { if (user != null && pw != null) .... } getConnection(getUser(p), getPassword(p))
  • 11. Applicative After getUser(props: Properties): Option[String] getPassword(props: Properties): Option[String] getConnection(user: String, pw: String): Connection = { if (user != null && pw != null) .... } getConnection(?, ?)
  • 13. Use Pointed f(a:A, b:B): C point fk: K[A => B => C]
  • 14. Applicative K[A => B] <*> K[A] == K[B] Apply the function
  • 15. Applicative K[A => B => C] <*> K[A] <*> K[B] == K[B => C] <*> K[B] == Currying ftw! K[C]
  • 16. Applicative K(f) <*> K(a) <*> K(b) Apply ‘f’ to ‘a’ and ‘b’ “inside” ‘K’
  • 17. Applicative K(f) <*> K(a) <*> K(b) Apply ‘f’ to ‘a’ and ‘b’ “inside” ‘K’
  • 18. Applicative Option Some(getConnection.curried) <*> user(p) <*> password(p)
  • 19. Applicative Option (user(p) <**> password(p))(mkConnection) mkConnection <$> user(p) <*> password(p)
  • 20. Applicative Future future(discount(_,_))) <*> future(amount) <*> future(rate) : Future[Double]
  • 21. Applicative List List(plus1) <*> List(1, 2, 3) List(2, 3, 4)
  • 22. Applicative List List(plus1, plus2) <*> List(1, 2, 3) == List(2, 3, 4, 3, 4, 5) ratings <*> clients
  • 23. Applicative ZipList List(plus1, plus2, plus3) <*> List(1, 2, 3) == List(1, 4, 6)
  • 24. Applicative State val add = (i: Int) => (j: Int) => i+j val times = (i: Int) => (j: Int) => i*j // 0 -> 1, 2, 3, 4 val s1 = modify((i: Int) => i+1) (add <$> s1 <*> s1)(1) == ? (times <$> s1 <*> s1)(1) == ?
  • 25. Applicative State current state +1=2 +1=3 (add <$> s1 <*> s1)(1) == (3, 5) add 2 previous states +1=2 +1=3 (times <$> s1 <*> s1)(1) == (3, 6) multiply 2 previous states
  • 26. Monad, remember? Unit def unit[A](a: =>A): M[A] Bind def bind[A, B](ma: M[A])(f: A => M[B]): M[B]
  • 27. Monad => Applicative Point def point(a: =>A) = Monad[M].unit(a) Apply def <*>[A, B](mf: M[A=>B])(ma: M[A]):M[B] = Monad[M].bind(mf) { f => Monad[M].bind(ma) { a => f(a) // M[B] } // M[B] } // M[B]
  • 28. The “for” loop val basket = Basket(orange, apple) var count = 0 val juices = Basket[Juice]() accumulation for (fruit <- basket) { count = count + 1 juices.add(fruit.press) “mapping” } same container for the result
  • 29.
  • 30. Traverse Traversable def traverse(f: A => F[B]): T[A] => F[T[B]] Applicative Same structure
  • 31. Traverse a List List(x, y, z): List[A] f: A => F[B]
  • 32. Traverse a List Apply ‘f’ to ‘z’ F(::) <*> F(z) <*> F(Nil) “Rebuild” the list  F(z :: Nil)
  • 33. Traverse a List F(::) <*> F(y) <*> F(z :: Nil)  F(y :: z :: Nil) F(::) <*> F(x) <*> F(y::z::Nil)  F(x :: y :: z :: Nil)
  • 34. Traverse a Binary Tree f x y z x x y z y z y z
  • 35. `sequence` def sequence[F: Applicative]: T[F[A]] => F[T[A]] = traverse(identity)
  • 36. `sequence` Execute concurrently? val examples: Seq[Example] = Seq(e1, e2, e3) Sequence of promises val executing: Seq[Promise[Result]] = examples.map(e => promise(e.execute)) val results: Promise[Seq[Result]] = executing.sequence Promise of a sequence
  • 37. Measure with Monoids trait Monoid[A] { val zero: A; def append(a: A, b: A): A } def measure[T: Traversable, M : Monoid] (f: A => M): T[A] => M Count elements: Int Monoid Accumulate elements: List Monoid
  • 38. `measure` def measure[T: Traversable, M : Monoid] (f: A => M) = traverse(a => f(a))
  • 39. `Const` “Phantom “ type case class Const[M, +A](value: M) new Applicative[Const[M, *]] { def point(a: =>A) = Const(Monoid[M].zero) def <*>(f: Const[M, A=>B], a: Const[M, A]) = Const(Monoid[M].append(f.value, a.value)) }
  • 40. Applicative => Monad Unit def unit[A](a: =>A) = Const(Monoid[M].zero) Bind def bind[A, B](ma: Const[M, A]) (f: A => Const[M, B]) = => but no value `a: A` to be found!
  • 41. `measure` Sum up all sizes def sumSizes[A : Size](seq: Seq[A]) = measure(a => Size[A].size(a))(seq) Collect all sizes def collectSizes[A : Size](seq: Seq[A]) = measure(a => List(Size[A].size(a)))(seq)
  • 42. `contents` def contents[A](tree: Tree[A]): List[A] = measure(a => List(a))(tree) x => List(x, y, z) y z
  • 43. `shape` def shape[A](tree: Tree[A]): Tree[Unit] = map(a => ())(tree) x => . y z . . def map[A, B](f: A => B): T[A] => traverse(a => Ident(f(a))) Identity monad
  • 44. `decompose` def decompose[A](tree: Tree[A]) = (contents(tree), shape(tree)) List(x, y, z) x => y z . . . Not very efficient…
  • 45. Applicative products case class Product[F1[_], F2[_], A]( first: F1[A], second: F2[A]) F1: Applicative, F2: Applicative def point[A, B](a: => A) = Product[F1, F2, B](Pointed[F1].point(a), Pointed[F2].point(a)) def <*>[A, B](f: Product[F1, F2, A => B]) = (c: Product[F1, F2, A]) => Product[F1, F2, B](f.first <*> c.first, f.second <*> c.second)
  • 46. `contents ⊗ shape` F1 = Const[List[A], *] F2 = Ident[*] val contents = (a: A) => Const[List[A], Unit](List(a)) val shape = (a: A) => Ident(()) val contentsAndShape: A => Product[Const[List[A], _], Ident[_], *] = contents ⊗ shape tree.traverse(contentsAndShape)
  • 47. Type indifference  One parameter type constructor trait Apply[F[_]] { def <*>[A, B](f: F[A => B]): F[A] => F[B] } List[Int]: Monoid Applicative => Const[List[Int], _] ({type l[a]=Const[List[Int], a]})#l
  • 48. Type indifference  Anonymous type ({type l[a]=Const[List[Int], a]})#l Type member ({type l[a]=Const[List[Int], a]})#l Type projection ({type l[a]=Const[List[Int], a]})#l type ApplicativeProduct = ({type l[a]=Product[Const[List[A],_],Ident[_],a]})#l
  • 49. Type indifference  Measure def measure[M : Monoid](f: T => M): M = traverse(t => Monoid[M].unit(f(t))).value For real… def measure[M : Monoid](f: A => M): M = traverse[(type l[a]=Const[M, a]})#l, A, Any] { t => Monoid[M].point(f(t)) }.value
  • 50. `collect` Accumulate and map def collect[F[_] : Applicative, A, B] (f: A => F[Unit], g: A => B) = { traverse { a: A => Applicative[F].point((u: Unit) => g(a)) <*> f(a)) } } val count = (i: Int) => state((n: Int) => (n+1, ())) val map = (i: Int) => i.toString tree.collect(count, map).apply(0)  (2, Bin(Leaf("1"), Leaf("2")))
  • 51. `disperse` Label and map def disperse(F[_] : Applicative, A, B, C] (f: F[B], g: A => B => C): T[A] => F[T[C]] val tree = Bin(Leaf(1.1), Bin(Leaf(2.2), Leaf(3.3))) val label = modify((n:Int) => n+1) val name = (p1:Double) => (p2:Int) => p1+" node is "+p2 tree.disperse(label, name).apply(0)._2  Bin(Leaf("1.1 node is 1"), Bin(Leaf("2.2 node is 2"), Leaf("3.3 node is 3")))
  • 52. EIP `measure` Map and count def measure[F[_] : Applicative, A, B] (f: F[B], g: A => C): T[A] => F[C] val crosses = modify((s: String) => s+"x") val map = (i: Int) => i.toString tree.measure(crosses, map).apply("") ("xxx", Bin(Leaf("1"), Bin(Leaf("2"), Leaf("3"))))
  • 53. Traversals mapped depend state depend on function map element create state on state element collect X X X disperse X X X measure X X traverse X X X X reduce X X reduceConst X map X
  • 54. Quizz def findMatches(divs: Seq[Int], nums: Seq[Int]) findMatches(Seq(2, 3, 4), Seq(1, 6, 7, 8, 9)) => Seq((2, 6), (3, 9), (4, 8)) With Traverse?
  • 55. Quizz def findMatches(divs: Seq[Int], nums: Seq[Int]) = { case class S(matches: Seq[(Int, Int)] = Seq[(Int, Int)](), remaining: Seq[Int]) val initialState = S(remaining = nums) def find(div: Int) = modify { (s: S) => s.remaining.find(_ % div == 0).map { (n: Int) => S(s.matches :+ div -> n, s.remaining - n) }.getOrElse(s) } divs.traverse(find).exec(initialState).matches }
  • 56. Composition val results = new ListBuffer for (a <- as) { val currentSize = a.size total += currentSize results.add(total) } F1 (map) then F2 (sum) F2 [F1[_]] => Applicative?
  • 57. `assemble` Shape + content => assembled def assemble[F[_] : Applicative, A]: (f: F[Unit], g: List[A]): T[A] => F[A] val shape: BinaryTree[Unit] = Bin(Leaf(()), Leaf(())) shape.assemble(List(1, 2))  (List(), Some(Bin(Leaf(1), Leaf(2)))) shape.assemble(List(1, 2, 3))  (List(3), Some(Bin(Leaf(1), Leaf(2)))) shape.assemble(List(1))  (List(), None)
  • 58. `assemble` def takeHead: State[List[B], Option[B]] = state { s: List[B] => s match { case Nil => (Nil, None) case x :: xs => (xs, Some(x)) } } F1: Option[_] An element to insert F2 :State[List[A], _] the rest of the list F2 [F1]: State[List[A], Option[_]] An applicative
  • 59. `assemble` def assemble[F[_] : Applicative, A] (f: F[Unit], list: List[A]) = traverse(takeHead).apply(list)
  • 60. Monadic composition M : Monad val f: B => M[C] val g: A => M[B] val h: A => M[C] = f • g Fusion? traverse(f) • traverse(g) == traverse(f • g)
  • 61. Monadic composition Yes if the Monad is commutative val xy = for { val yx = for { x <- (mx: M[X]) y <- (my: M[Y]) xy == yx y <- (my: M[Y]) x <- (mx: M[X]) } yield (x, y) } yield (x, y) State is *not* commutative val mx = state((n: Int) => (n+1, n+1)) val my = state((n: Int) => (n+1, n+1)) xy.apply(0) == (2, (1, 2)) yx.apply(0) == (2, (2, 1))
  • 62. Applicative composition vs Monadic composition Not commutative functions => fusion Seq(1,2,3).traverse(times2 ⊙ plus1) == 4  State[Int, State[Int, Seq[Int]]] Seq(1,2,3).traverse(times2) ⊙ Seq(1,2,3).traverse(plus1) == 4  State[Int, Seq[State[Int, Int]]
  • 63. Monadic composition: conjecture Commutative functions val plus1 = (a: A) => state((n: Int) => (n+1, a)) val plus2 = (a: A) => state((n: Int) => (n+2, a)) val times2 = (a: A) => state((n: Int) => (n*2, a)) plus1 and plus2 are commutative plus1 and times2 are not commutative: (0 + 1) * 2 != (0 * 2) + 1
  • 64. Monadic composition: conjecture Commutative functions => fusion Seq(1,2,3).traverse(plus2 ∎ plus1) == 10 Seq(1,2,3).traverse(plus2) ∎ Seq(1,2,3).traverse(plus1) == 10 Not commutative functions => no fusion Seq(1,2,3).traverse(times2 ∎ plus1) == 22 Seq(1,2,3).traverse(times2) ∎ Seq(1,2,3).traverse(plus1) == 32