SlideShare a Scribd company logo
Ittay Dror
             ittayd@tikalk.com
             @ittayd
             http://www.tikalk.com/blogs/ittayd




    Functional Programming
     From OOP perspective

26-Oct-11
What is FP?



     2        WWW.TIKALK.COM
“a programming paradigm that
    treats computation as the
   evaluation of mathematical
 functions and avoids state and
          mutable data”


               3             WWW.TIKALK.COM
• Functions as values
• Immutable data structures
• Mathematical models
• Referential transparency




                    4         WWW.TIKALK.COM
Why Should We Care?



         5        WWW.TIKALK.COM
Not everything is an
      object


         6             WWW.TIKALK.COM
May Forget


                                         Nothing to
service.init                             return?

val data = service.get
service.close             May forget /
                          call twice
println(data)




                     7                                WWW.TIKALK.COM
IOC



 8    WWW.TIKALK.COM
class Service {
  def withData[T](f: Data => T) {
    init
    if (thereIsData)
      f(getData)
    close
  }
}

service.witData(println)

                     9              WWW.TIKALK.COM
Simplification



      10         WWW.TIKALK.COM
In OOP:
 trait DataConsumer[T] {
   def withData(data: Data): T
 {


In FP:
 Data => T



                     11          WWW.TIKALK.COM
Factories are partially
  applied functions


           12         WWW.TIKALK.COM
val factory_: File => String => User =
  file => name => readFromFile(name)

val factory: String => User = factory_(usersFile)




                    Look ma, no interfaces
                        13                 WWW.TIKALK.COM
Security



   14      WWW.TIKALK.COM
Immutable data is
   sharable


        15          WWW.TIKALK.COM
Instead of modifying,
     create new


          16        WWW.TIKALK.COM
Abstraction



     17       WWW.TIKALK.COM
Functors, Applicatives,
      Monads


           18         WWW.TIKALK.COM
Usual way of describing:


                  WTF??

            19        WWW.TIKALK.COM
OO way: Design Patterns



           20       WWW.TIKALK.COM
Values in a context



         21           WWW.TIKALK.COM
Option[X]
List[X]
Future[X]


            22   WWW.TIKALK.COM
trait Future[A] {
          def get: A
        {
def findUser(name: String): Future[User] = …

…
val future = findUser(userName)
val user = future.get
println(user)

                      23               WWW.TIKALK.COM
trait Future[A] {
      def onReady(f: A => Unit)
    }


val future = findUser(userName)
future.onReady{user => println(user)}


                      24                WWW.TIKALK.COM
Functor




   25     WWW.TIKALK.COM
trait Future[A] {
  def map[B](f: A => B): Future[B]
{



val user = findUser(userName)
val age: Future[Int] = user.map{user => user.age}




                        26                 WWW.TIKALK.COM
val result = new ArrayList(list.size)
for (i <- 0 to (list.size - 1)) {
  result += compute(list(i))
}
result


                    Vs.
list.map(compute)


                      27                WWW.TIKALK.COM
class ComputeTask extends RecursiveTask {
  def compute = // split and call
invokeAll...
{
val pool = new ForkJoinPool()
val task = new ComputeTask()
pool.invoke(task)

                 Vs.
list.par.map(compute)


                        28           WWW.TIKALK.COM
trait Future[A] {
  def get: A

    def map[B](f: A => B) = new Future[B] {
      def get = f(Future.this.get)
    {
{




                       29              WWW.TIKALK.COM
def marry(man: User, woman: User): Family = ⠄⠄⠄

val joe = findUser("joe")
val jane = findUser("jane")




   Get Joe and Jane married


                        30                WWW.TIKALK.COM
Future[Family]



                                    User => Family


joe.map{joe => jane.map{jane => marry(joe, jane)}}


                           User => Future[Family]



                   Future[Future[Family]]


                           31                        WWW.TIKALK.COM
Attempt I
trait Future[A] {
  def apply[B, C](other: Future[B], f: (A, B) =>
C): Future[C]
}


 joe.apply(jane, marry)




                          32               WWW.TIKALK.COM
It is easier to work with
single argument functions


             33          WWW.TIKALK.COM
Curried Functions
val func: Int => Int => Int = a => b => a + b




  (marry _).curried


                        34                 WWW.TIKALK.COM
Attempt II

trait Future[A] {
  ...

    def apply[B](f: Future[A => B]): Future[B]
{




                          35                 WWW.TIKALK.COM
Future[User => Family]



                         User => User => Family


joe.apply(jane.map((marry _).curried))


               User => Future[Family]




                    36                        WWW.TIKALK.COM
We can do better



       37          WWW.TIKALK.COM
val marry: Future[User => User => Family] = Future(marry)

val partial: Future[User => Family] = futureMarry.apply(joe)

val family: Future[Family] = partial.apply(jane)



Future(marry).apply(joe).apply(jane)

Future(marry)(joe)(jane)




            Using apply compiles iff A is a function
                              38                    WWW.TIKALK.COM
Applicative Functors



         39            WWW.TIKALK.COM
• Put value in context
• Apply function in a context to value in
a context




                     40                     WWW.TIKALK.COM
trait Future[A] {
  def apply[B, C](b: Future[B])
                 (implicit ev: A <:< (B => C))
                 : Future[C]
{



object Future {
  def apply[A](a: A): Future[A]
}




       Future((marry _).curried)(joe)(jane)
                        41                 WWW.TIKALK.COM
trait Future[A] {
  def apply[B, C](b: Future[B])
                 (implicit ev: A <:< (B => C)) =
    new Future[C] {
      def get = Future.this.get(b.get)
    {
{
object Future {
  def apply[A](a: A) = new Future[A] {
      def get = a
    }
  }
}


                        42                 WWW.TIKALK.COM
Composing Functions that
Return Value in a Context


            43        WWW.TIKALK.COM
Composing Special
           Functions
def findUser(name: String): Future[User]
def findProfile(user: User): Future[Profile]




findProfile(findUser("joe"))


                        44                 WWW.TIKALK.COM
Monads



  45     WWW.TIKALK.COM
trait Future[A] {
  ...
  def flatMap[B](f: A => Future[B]): Future[B]
}




findUser("joe").flatMap(findProfile)




                        46                 WWW.TIKALK.COM
trait Future[A] {
  ...
  def flatMap[B](f: A => Future[B]): Future[B] =
    new Future[B] {
      def get = f(Future.this.get).get
    }
  }
}




                        47                 WWW.TIKALK.COM
All Together

trait Context[A] {
  def map[B](f: A => B): Context[B]
  def apply[B, C](b: Context[B])
                 (implicit ev: A <:< (B => C)): Context[C]
  def flatMap[B](f: A => Context[B]): Context[B]
}


                            48                    WWW.TIKALK.COM
Laws



 49    WWW.TIKALK.COM
Idiomatic “interface” for
    context classes


            50         WWW.TIKALK.COM
Monoid
• For type A to be (have) a Monoid:
   • Binary operation „•„: (A, A) => A
   • Identity element „∅‟: A




                     51                  WWW.TIKALK.COM
• String is a Monoid (2 ways):
   • Binary operation: append or prepend
   • Identity element: “”




• Int is a Monoid (2 ways):
   • Binary operation: + or *
   • Identity element: 0 or 1



                       52                  WWW.TIKALK.COM
• Future[A] is a monoid, if A is a monoid
   • Binary operation: Future(A#•)
      • (Future as applicative)
   • Identity element: Future(A#identity)




                       53                   WWW.TIKALK.COM
Monoids generalize folds



           54        WWW.TIKALK.COM
Folds: reduce values to
          one
• List(x,y,z) => ∅ • x • y • z
• Option(x) => if Some ∅ • x
                else ∅




                       55        WWW.TIKALK.COM
Unfolds: Create values
 from initial value and
        function
• 1, if (a < 3) Some(a, a+1) else None
   • Some(1, 2), Some(2, 3), None
   • ∅•1•2•3
   • If our monoid is a List:
       • Nil ++ List(1) ++ List(2) ++ List(3)
       • List(1,2,3)

                        56                      WWW.TIKALK.COM
Since many things are
monoids, we can have
many generic algorithms


           57       WWW.TIKALK.COM
Problems with subtyping:
 • Namespace pollution
 • Need to control the class
 • Describes behavior, not „is-a‟
 • Sometimes ability is conditional:
    • Future is a monoid if A is a monoid
 • Sometimes there are different definitions
    • E.g., 2 monoids for integers
 • Maybe a class has several facets
    • E.g. context of 2 values
                     58                   WWW.TIKALK.COM
Typeclass

• Define an API
• Create instance for each class that
can conform to the API




                    59                  WWW.TIKALK.COM
Java example:
 Comparator


      60        WWW.TIKALK.COM
trait Functor[F[_]] {
  def map[A, B](fa: F[A], f: A => B): F[B]
{
implicit object FutureHasFunctor
  extends Functor[Future] {
  def map[A, B](t: Future[A], f: A => B) =
    new Future[B] {
      def get = f(t.get)
    }
  }
{
def age(name: String) = {
  val functor = implicitly[Functor[Future]]
  functor.map(findUser(name), {u: User => u.age})
}
                        61                   WWW.TIKALK.COM
def age(name: String)
       (implicit functor: Functor[Future]) {
  functor.map(findUser(name), {u: User => u.age})
}




                        62                 WWW.TIKALK.COM
def age[F[_] : Functor](name: String) {
  functor.map(findUser(name), {u: User => u.age})
}




                        63                 WWW.TIKALK.COM
Generic Programming



         64       WWW.TIKALK.COM
def sequence[A, AP[_] : Applicative]
            (apas: List[AP[A]]): AP[List[A]]




val futureOfList = sequence(listOfFutures)

                        65                   WWW.TIKALK.COM
trait Applicative[AP[_]] {
  def pure[A](a: A) : AP[A]
  def apply[A, B](ap: AP[A => B], a: AP[A]): AP[B]
{




                        66                 WWW.TIKALK.COM
It is NOT important if you
don’t understand the next
             slide


             67         WWW.TIKALK.COM
def sequence[A, AP[_] : Applicative](apas: List[AP[A]]):
  AP[List[A]] = {

    val applicative = implicitly[Applicative[AP]]
    import applicative._
    val cons = pure{x: A => xs: List[A] => x :: xs}

    apas match {
      case Nil => pure(Nil)
      case apa :: apas =>
        val recursion = sequence(apas) // AP[List[A]]
        val partial = apply(cons, apa) // AP[List[A]=>List[A]]
        apply(partial, recursion)
    }
}


                               68                    WWW.TIKALK.COM
Beyond



  69     WWW.TIKALK.COM
val m = Map[Int, Int]()
m.map{case (k, v) => k + v}




                     70       WWW.TIKALK.COM
def map[B, That](f: A => B)
    (implicit bf: CanBuildFrom[Repr, B, That])
    : That




                        71                 WWW.TIKALK.COM
?
72   WWW.TIKALK.COM

More Related Content

What's hot (20)

PDF
How to extend map? Or why we need collections redesign? - Scalar 2017
Szymon Matejczyk
 
ODP
WorkingWithSlick2.1.0
Knoldus Inc.
 
PDF
Typelevel summit
Marina Sigaeva
 
PPT
Oop lecture9 13
Shahriar Robbani
 
PDF
Herding types with Scala macros
Marina Sigaeva
 
PDF
Json and SQL DB serialization Introduction with Play! and Slick
Stephen Kemmerling
 
PDF
Basic data structures in python
Lifna C.S
 
PDF
Scala.io
Steve Gury
 
PDF
The Ring programming language version 1.2 book - Part 19 of 84
Mahmoud Samir Fayed
 
PPTX
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Vyacheslav Arbuzov
 
PDF
The Ring programming language version 1.5.2 book - Part 29 of 181
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.8 book - Part 43 of 202
Mahmoud Samir Fayed
 
PPTX
Seminar PSU 10.10.2014 mme
Vyacheslav Arbuzov
 
PPTX
Introduction to Monads in Scala (2)
stasimus
 
PDF
Python speleology
Andrés J. Díaz
 
DOCX
CLUSTERGRAM
Dr. Volkan OBAN
 
PDF
Perm winter school 2014.01.31
Vyacheslav Arbuzov
 
PDF
The Ring programming language version 1.5 book - Part 8 of 31
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.9 book - Part 46 of 210
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.4 book - Part 8 of 30
Mahmoud Samir Fayed
 
How to extend map? Or why we need collections redesign? - Scalar 2017
Szymon Matejczyk
 
WorkingWithSlick2.1.0
Knoldus Inc.
 
Typelevel summit
Marina Sigaeva
 
Oop lecture9 13
Shahriar Robbani
 
Herding types with Scala macros
Marina Sigaeva
 
Json and SQL DB serialization Introduction with Play! and Slick
Stephen Kemmerling
 
Basic data structures in python
Lifna C.S
 
Scala.io
Steve Gury
 
The Ring programming language version 1.2 book - Part 19 of 84
Mahmoud Samir Fayed
 
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Vyacheslav Arbuzov
 
The Ring programming language version 1.5.2 book - Part 29 of 181
Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 43 of 202
Mahmoud Samir Fayed
 
Seminar PSU 10.10.2014 mme
Vyacheslav Arbuzov
 
Introduction to Monads in Scala (2)
stasimus
 
Python speleology
Andrés J. Díaz
 
CLUSTERGRAM
Dr. Volkan OBAN
 
Perm winter school 2014.01.31
Vyacheslav Arbuzov
 
The Ring programming language version 1.5 book - Part 8 of 31
Mahmoud Samir Fayed
 
The Ring programming language version 1.9 book - Part 46 of 210
Mahmoud Samir Fayed
 
The Ring programming language version 1.4 book - Part 8 of 30
Mahmoud Samir Fayed
 

Similar to Functional Programming from OO perspective (Sayeret Lambda lecture) (20)

PPTX
Taxonomy of Scala
shinolajla
 
PDF
Scala at GenevaJUG by Iulian Dragos
GenevaJUG
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
A bit about Scala
Vladimir Parfinenko
 
PDF
Monads and Monoids by Oleksiy Dyagilev
JavaDayUA
 
PDF
ハイブリッド言語Scalaを使う
bpstudy
 
PDF
Scala or functional programming from a python developer's perspective
gabalese
 
PDF
Scala In The Wild
djspiewak
 
PDF
Introduction to Scala
Aleksandar Prokopec
 
PDF
Scala for Java Programmers
Eric Pederson
 
PPTX
Intro to Functional Programming in Scala
Shai Yallin
 
PDF
Scala for Java Developers - Intro
David Copeland
 
KEY
Building a Mongo DSL in Scala at Hot Potato
MongoDB
 
PPTX
Scala best practices
Alexander Zaidel
 
PDF
Generic Functional Programming with Type Classes
Tapio Rautonen
 
PDF
Functional programming in Scala
Damian Jureczko
 
PDF
Getting Started With Scala
Xebia IT Architects
 
Taxonomy of Scala
shinolajla
 
Scala at GenevaJUG by Iulian Dragos
GenevaJUG
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
A bit about Scala
Vladimir Parfinenko
 
Monads and Monoids by Oleksiy Dyagilev
JavaDayUA
 
ハイブリッド言語Scalaを使う
bpstudy
 
Scala or functional programming from a python developer's perspective
gabalese
 
Scala In The Wild
djspiewak
 
Introduction to Scala
Aleksandar Prokopec
 
Scala for Java Programmers
Eric Pederson
 
Intro to Functional Programming in Scala
Shai Yallin
 
Scala for Java Developers - Intro
David Copeland
 
Building a Mongo DSL in Scala at Hot Potato
MongoDB
 
Scala best practices
Alexander Zaidel
 
Generic Functional Programming with Type Classes
Tapio Rautonen
 
Functional programming in Scala
Damian Jureczko
 
Getting Started With Scala
Xebia IT Architects
 
Ad

Recently uploaded (20)

PPTX
Top Managed Service Providers in Los Angeles
Captain IT
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
Impact of IEEE Computer Society in Advancing Emerging Technologies including ...
Hironori Washizaki
 
PDF
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PDF
Wojciech Ciemski for Top Cyber News MAGAZINE. June 2025
Dr. Ludmila Morozova-Buss
 
PDF
Empowering Cloud Providers with Apache CloudStack and Stackbill
ShapeBlue
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
PDF
Ampere Offers Energy-Efficient Future For AI And Cloud
ShapeBlue
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
Smart Air Quality Monitoring with Serrax AQM190 LITE
SERRAX TECHNOLOGIES LLP
 
PDF
Meetup Kickoff & Welcome - Rohit Yadav, CSIUG Chairman
ShapeBlue
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
PDF
Predicting the unpredictable: re-engineering recommendation algorithms for fr...
Speck&Tech
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PPT
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
Top Managed Service Providers in Los Angeles
Captain IT
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
Impact of IEEE Computer Society in Advancing Emerging Technologies including ...
Hironori Washizaki
 
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
Wojciech Ciemski for Top Cyber News MAGAZINE. June 2025
Dr. Ludmila Morozova-Buss
 
Empowering Cloud Providers with Apache CloudStack and Stackbill
ShapeBlue
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
Ampere Offers Energy-Efficient Future For AI And Cloud
ShapeBlue
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
Smart Air Quality Monitoring with Serrax AQM190 LITE
SERRAX TECHNOLOGIES LLP
 
Meetup Kickoff & Welcome - Rohit Yadav, CSIUG Chairman
ShapeBlue
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
Predicting the unpredictable: re-engineering recommendation algorithms for fr...
Speck&Tech
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
Ad

Functional Programming from OO perspective (Sayeret Lambda lecture)

  • 1. Ittay Dror [email protected] @ittayd http://www.tikalk.com/blogs/ittayd Functional Programming From OOP perspective 26-Oct-11
  • 2. What is FP? 2 WWW.TIKALK.COM
  • 3. “a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data” 3 WWW.TIKALK.COM
  • 4. • Functions as values • Immutable data structures • Mathematical models • Referential transparency 4 WWW.TIKALK.COM
  • 5. Why Should We Care? 5 WWW.TIKALK.COM
  • 6. Not everything is an object 6 WWW.TIKALK.COM
  • 7. May Forget Nothing to service.init return? val data = service.get service.close May forget / call twice println(data) 7 WWW.TIKALK.COM
  • 8. IOC 8 WWW.TIKALK.COM
  • 9. class Service { def withData[T](f: Data => T) { init if (thereIsData) f(getData) close } } service.witData(println) 9 WWW.TIKALK.COM
  • 10. Simplification 10 WWW.TIKALK.COM
  • 11. In OOP: trait DataConsumer[T] { def withData(data: Data): T { In FP: Data => T 11 WWW.TIKALK.COM
  • 12. Factories are partially applied functions 12 WWW.TIKALK.COM
  • 13. val factory_: File => String => User = file => name => readFromFile(name) val factory: String => User = factory_(usersFile) Look ma, no interfaces 13 WWW.TIKALK.COM
  • 14. Security 14 WWW.TIKALK.COM
  • 15. Immutable data is sharable 15 WWW.TIKALK.COM
  • 16. Instead of modifying, create new 16 WWW.TIKALK.COM
  • 17. Abstraction 17 WWW.TIKALK.COM
  • 18. Functors, Applicatives, Monads 18 WWW.TIKALK.COM
  • 19. Usual way of describing: WTF?? 19 WWW.TIKALK.COM
  • 20. OO way: Design Patterns 20 WWW.TIKALK.COM
  • 21. Values in a context 21 WWW.TIKALK.COM
  • 22. Option[X] List[X] Future[X] 22 WWW.TIKALK.COM
  • 23. trait Future[A] { def get: A { def findUser(name: String): Future[User] = … … val future = findUser(userName) val user = future.get println(user) 23 WWW.TIKALK.COM
  • 24. trait Future[A] { def onReady(f: A => Unit) } val future = findUser(userName) future.onReady{user => println(user)} 24 WWW.TIKALK.COM
  • 25. Functor 25 WWW.TIKALK.COM
  • 26. trait Future[A] { def map[B](f: A => B): Future[B] { val user = findUser(userName) val age: Future[Int] = user.map{user => user.age} 26 WWW.TIKALK.COM
  • 27. val result = new ArrayList(list.size) for (i <- 0 to (list.size - 1)) { result += compute(list(i)) } result Vs. list.map(compute) 27 WWW.TIKALK.COM
  • 28. class ComputeTask extends RecursiveTask { def compute = // split and call invokeAll... { val pool = new ForkJoinPool() val task = new ComputeTask() pool.invoke(task) Vs. list.par.map(compute) 28 WWW.TIKALK.COM
  • 29. trait Future[A] { def get: A def map[B](f: A => B) = new Future[B] { def get = f(Future.this.get) { { 29 WWW.TIKALK.COM
  • 30. def marry(man: User, woman: User): Family = ⠄⠄⠄ val joe = findUser("joe") val jane = findUser("jane") Get Joe and Jane married 30 WWW.TIKALK.COM
  • 31. Future[Family] User => Family joe.map{joe => jane.map{jane => marry(joe, jane)}} User => Future[Family] Future[Future[Family]] 31 WWW.TIKALK.COM
  • 32. Attempt I trait Future[A] { def apply[B, C](other: Future[B], f: (A, B) => C): Future[C] } joe.apply(jane, marry) 32 WWW.TIKALK.COM
  • 33. It is easier to work with single argument functions 33 WWW.TIKALK.COM
  • 34. Curried Functions val func: Int => Int => Int = a => b => a + b (marry _).curried 34 WWW.TIKALK.COM
  • 35. Attempt II trait Future[A] { ... def apply[B](f: Future[A => B]): Future[B] { 35 WWW.TIKALK.COM
  • 36. Future[User => Family] User => User => Family joe.apply(jane.map((marry _).curried)) User => Future[Family] 36 WWW.TIKALK.COM
  • 37. We can do better 37 WWW.TIKALK.COM
  • 38. val marry: Future[User => User => Family] = Future(marry) val partial: Future[User => Family] = futureMarry.apply(joe) val family: Future[Family] = partial.apply(jane) Future(marry).apply(joe).apply(jane) Future(marry)(joe)(jane) Using apply compiles iff A is a function 38 WWW.TIKALK.COM
  • 39. Applicative Functors 39 WWW.TIKALK.COM
  • 40. • Put value in context • Apply function in a context to value in a context 40 WWW.TIKALK.COM
  • 41. trait Future[A] { def apply[B, C](b: Future[B]) (implicit ev: A <:< (B => C)) : Future[C] { object Future { def apply[A](a: A): Future[A] } Future((marry _).curried)(joe)(jane) 41 WWW.TIKALK.COM
  • 42. trait Future[A] { def apply[B, C](b: Future[B]) (implicit ev: A <:< (B => C)) = new Future[C] { def get = Future.this.get(b.get) { { object Future { def apply[A](a: A) = new Future[A] { def get = a } } } 42 WWW.TIKALK.COM
  • 43. Composing Functions that Return Value in a Context 43 WWW.TIKALK.COM
  • 44. Composing Special Functions def findUser(name: String): Future[User] def findProfile(user: User): Future[Profile] findProfile(findUser("joe")) 44 WWW.TIKALK.COM
  • 45. Monads 45 WWW.TIKALK.COM
  • 46. trait Future[A] { ... def flatMap[B](f: A => Future[B]): Future[B] } findUser("joe").flatMap(findProfile) 46 WWW.TIKALK.COM
  • 47. trait Future[A] { ... def flatMap[B](f: A => Future[B]): Future[B] = new Future[B] { def get = f(Future.this.get).get } } } 47 WWW.TIKALK.COM
  • 48. All Together trait Context[A] { def map[B](f: A => B): Context[B] def apply[B, C](b: Context[B]) (implicit ev: A <:< (B => C)): Context[C] def flatMap[B](f: A => Context[B]): Context[B] } 48 WWW.TIKALK.COM
  • 49. Laws 49 WWW.TIKALK.COM
  • 50. Idiomatic “interface” for context classes 50 WWW.TIKALK.COM
  • 51. Monoid • For type A to be (have) a Monoid: • Binary operation „•„: (A, A) => A • Identity element „∅‟: A 51 WWW.TIKALK.COM
  • 52. • String is a Monoid (2 ways): • Binary operation: append or prepend • Identity element: “” • Int is a Monoid (2 ways): • Binary operation: + or * • Identity element: 0 or 1 52 WWW.TIKALK.COM
  • 53. • Future[A] is a monoid, if A is a monoid • Binary operation: Future(A#•) • (Future as applicative) • Identity element: Future(A#identity) 53 WWW.TIKALK.COM
  • 54. Monoids generalize folds 54 WWW.TIKALK.COM
  • 55. Folds: reduce values to one • List(x,y,z) => ∅ • x • y • z • Option(x) => if Some ∅ • x else ∅ 55 WWW.TIKALK.COM
  • 56. Unfolds: Create values from initial value and function • 1, if (a < 3) Some(a, a+1) else None • Some(1, 2), Some(2, 3), None • ∅•1•2•3 • If our monoid is a List: • Nil ++ List(1) ++ List(2) ++ List(3) • List(1,2,3) 56 WWW.TIKALK.COM
  • 57. Since many things are monoids, we can have many generic algorithms 57 WWW.TIKALK.COM
  • 58. Problems with subtyping: • Namespace pollution • Need to control the class • Describes behavior, not „is-a‟ • Sometimes ability is conditional: • Future is a monoid if A is a monoid • Sometimes there are different definitions • E.g., 2 monoids for integers • Maybe a class has several facets • E.g. context of 2 values 58 WWW.TIKALK.COM
  • 59. Typeclass • Define an API • Create instance for each class that can conform to the API 59 WWW.TIKALK.COM
  • 60. Java example: Comparator 60 WWW.TIKALK.COM
  • 61. trait Functor[F[_]] { def map[A, B](fa: F[A], f: A => B): F[B] { implicit object FutureHasFunctor extends Functor[Future] { def map[A, B](t: Future[A], f: A => B) = new Future[B] { def get = f(t.get) } } { def age(name: String) = { val functor = implicitly[Functor[Future]] functor.map(findUser(name), {u: User => u.age}) } 61 WWW.TIKALK.COM
  • 62. def age(name: String) (implicit functor: Functor[Future]) { functor.map(findUser(name), {u: User => u.age}) } 62 WWW.TIKALK.COM
  • 63. def age[F[_] : Functor](name: String) { functor.map(findUser(name), {u: User => u.age}) } 63 WWW.TIKALK.COM
  • 64. Generic Programming 64 WWW.TIKALK.COM
  • 65. def sequence[A, AP[_] : Applicative] (apas: List[AP[A]]): AP[List[A]] val futureOfList = sequence(listOfFutures) 65 WWW.TIKALK.COM
  • 66. trait Applicative[AP[_]] { def pure[A](a: A) : AP[A] def apply[A, B](ap: AP[A => B], a: AP[A]): AP[B] { 66 WWW.TIKALK.COM
  • 67. It is NOT important if you don’t understand the next slide 67 WWW.TIKALK.COM
  • 68. def sequence[A, AP[_] : Applicative](apas: List[AP[A]]): AP[List[A]] = { val applicative = implicitly[Applicative[AP]] import applicative._ val cons = pure{x: A => xs: List[A] => x :: xs} apas match { case Nil => pure(Nil) case apa :: apas => val recursion = sequence(apas) // AP[List[A]] val partial = apply(cons, apa) // AP[List[A]=>List[A]] apply(partial, recursion) } } 68 WWW.TIKALK.COM
  • 69. Beyond 69 WWW.TIKALK.COM
  • 70. val m = Map[Int, Int]() m.map{case (k, v) => k + v} 70 WWW.TIKALK.COM
  • 71. def map[B, That](f: A => B) (implicit bf: CanBuildFrom[Repr, B, That]) : That 71 WWW.TIKALK.COM
  • 72. ? 72 WWW.TIKALK.COM