SlideShare uma empresa Scribd logo
1 de 64
Baixar para ler offline
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

Mais conteúdo relacionado

Mais procurados

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
 
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
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
stasimus
 

Mais procurados (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
 

Destaque (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
 

Semelhante a The Essence of the Iterator Pattern (pdf)

Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
league
 

Semelhante a 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
ThesisThesis
Thesis
 
Thesis PPT
Thesis PPTThesis PPT
Thesis PPT
 
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...
 

Mais de Eric Torreborre

Mais de 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
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Último (20)

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 

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