SlideShare uma empresa Scribd logo
1 de 64
Computati     Functo
    on           r

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

Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Luka Jacobowitz
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)stasimus
 
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 VyacheslavVyacheslav Arbuzov
 
Programs in array using SWIFT
Programs in array using SWIFTPrograms in array using SWIFT
Programs in array using SWIFTvikram mahendra
 
하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3Kwang Yul Seo
 
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 CSPFilippo Vitale
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monadskenbot
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4Kwang Yul Seo
 
Why The Free Monad isn't Free
Why The Free Monad isn't FreeWhy The Free Monad isn't Free
Why The Free Monad isn't FreeKelley Robinson
 
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 185Mahmoud Samir Fayed
 

Mais procurados (17)

Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
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
 
Functor Laws
Functor LawsFunctor Laws
Functor Laws
 
02 arrays
02 arrays02 arrays
02 arrays
 
Programs in array using SWIFT
Programs in array using SWIFTPrograms in array using SWIFT
Programs in array using SWIFT
 
Data import-cheatsheet
Data import-cheatsheetData import-cheatsheet
Data import-cheatsheet
 
Perm winter school 2014.01.31
Perm winter school 2014.01.31Perm winter school 2014.01.31
Perm winter school 2014.01.31
 
하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3
 
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
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monads
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4
 
Seminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mmeSeminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mme
 
Why The Free Monad isn't Free
Why The Free Monad isn't FreeWhy The Free Monad isn't Free
Why The Free Monad isn't Free
 
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
 
20090622 Bp Study#22
20090622 Bp Study#2220090622 Bp Study#22
20090622 Bp Study#22
 
Seminar psu 20.10.2013
Seminar psu 20.10.2013Seminar psu 20.10.2013
Seminar psu 20.10.2013
 

Destaque

Destaque (7)

Iterator Pattern
Iterator PatternIterator Pattern
Iterator Pattern
 
C# Strings
C# StringsC# Strings
C# Strings
 
Iterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternIterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design pattern
 
Iterator
IteratorIterator
Iterator
 
Iterator Design Pattern
Iterator Design PatternIterator Design Pattern
Iterator Design Pattern
 
Programming in c#
Programming in c#Programming in c#
Programming in c#
 
C# Tutorial
C# Tutorial C# Tutorial
C# Tutorial
 

Semelhante a Here is how I would implement findMatches using traverse:def findMatchesF_: Applicative(divs: SeqInt, nums: SeqInt): FSeq(Int, Int) = { traverse(div => nums.traverse(n => if(n % div == 0) ApplicativeF.pure((div, n)) else ApplicativeF.pure(None))) (divs).map(_.flatten)}// Usage:findMatches(Seq(2,3,4), Seq(1,6,7,8,9))This traverses the divs, mapping each to a traverse of nums to find matches

Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adtsHang 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 2Hang Zhao
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystifiedAlessandro Lacava
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and EffectsRaymond Roestenburg
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type ClassesTapio Rautonen
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aidDavid Hoyt
 
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 worldDebasish Ghosh
 
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 & AnalyticsJohn De Goes
 
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 HaskellMichel Rijnders
 
Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Filippo Vitale
 

Semelhante a Here is how I would implement findMatches using traverse:def findMatchesF_: Applicative(divs: SeqInt, nums: SeqInt): FSeq(Int, Int) = { traverse(div => nums.traverse(n => if(n % div == 0) ApplicativeF.pure((div, n)) else ApplicativeF.pure(None))) (divs).map(_.flatten)}// Usage:findMatches(Seq(2,3,4), Seq(1,6,7,8,9))This traverses the divs, mapping each to a traverse of nums to find matches (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
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Monadologie
MonadologieMonadologie
Monadologie
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aid
 
purrr.pdf
purrr.pdfpurrr.pdf
purrr.pdf
 
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
 
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
 
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
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Map, Reduce and Filter in Swift
Map, Reduce and Filter in SwiftMap, Reduce and Filter in Swift
Map, Reduce and Filter in Swift
 
Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015
 

Mais de 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.pdfEric Torreborre
 
The many faces of modularity
The many faces of modularityThe many faces of modularity
The many faces of modularityEric 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 lookingEric 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-confEric 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 kitchenEric 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 trilogyEric Torreborre
 
Pratical eff-scalaitaly-2017
Pratical eff-scalaitaly-2017Pratical eff-scalaitaly-2017
Pratical eff-scalaitaly-2017Eric Torreborre
 
Pratical eff monad at Scaladays Chicago
Pratical eff monad at Scaladays ChicagoPratical eff monad at Scaladays Chicago
Pratical eff monad at Scaladays ChicagoEric 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 allEric Torreborre
 
Data generation, the hard parts
Data generation, the hard partsData generation, the hard parts
Data generation, the hard partsEric 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 ScalaEric Torreborre
 
Datatypes for the real world
Datatypes for the real worldDatatypes for the real world
Datatypes for the real worldEric Torreborre
 
Specs2 whirlwind tour at Scaladays 2014
Specs2 whirlwind tour at Scaladays 2014Specs2 whirlwind tour at Scaladays 2014
Specs2 whirlwind tour at Scaladays 2014Eric 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* FPEric 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
 
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
 
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
 

Último

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 

Último (20)

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 

Here is how I would implement findMatches using traverse:def findMatchesF_: Applicative(divs: SeqInt, nums: SeqInt): FSeq(Int, Int) = { traverse(div => nums.traverse(n => if(n % div == 0) ApplicativeF.pure((div, n)) else ApplicativeF.pure(None))) (divs).map(_.flatten)}// Usage:findMatches(Seq(2,3,4), Seq(1,6,7,8,9))This traverses the divs, mapping each to a traverse of nums to find matches

  • 1.
  • 2. Computati Functo on r 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