KEMBAR78
Introduction to Monads in Scala (1) | PPTX
Monads
              Part 1
functional programming with scala
Where r the verbs lost?
Thinking in Use Cases


   get the coffee
   meet with colleagues on the kitchen
   read emails
   review social media
   update the workspace
   write the code
Thinking in Java

CompanyHolder.getStuffFactoryBuilder().
  buildCurrentState().
  find(Rooms.KITCHEN, CoffeMachine.Any).
  get(0).
  run(new CoffeeJob( me.getHabitsStore().find("coffe").
            mapToJobMachnie(), null));
Thinking in Java

Need an update:

new SVNUpdateJob(myProject).go();

•   execute
•   process
•   run
•   start
•   doIt
Thinking in Java

Check Gmail

MySmartProxyHack.go();


go via Hack or Job – action name
                         isn't important
Q

How many times u were not lucky with
fact that do is the keyword?

ProjectManager.do() vs manage
SecurityProcessor.do() vs process
Guava from G

Bad library: it makes me feeling smell

Preconditions.checkArgument(...)
   vs
checkArgument(...)

with
static import... but this is a way for nonlazy dudes
 in Java
Patriots in Java

First action is create, get, find, build, ...?

Use a Spring, Guice!!!
Other ways of thinking

C and C++
Python
Evil?

We r smart – look into Python,
Ruby, Java Script or Perl – gun meat.

Im smart enough to understand
AbstractProxyMediator or
NotificationStrategyFactory
– they even don't have it!
Monad is …
Monad is
Usually articles that start with words like
"monad" and "functor" quickly devolve into
soup of Greek letters. That's because both are
abstract concepts in a branch of mathematics
called category theory and explaining them
completely is a mathematical exercise.
                                         JAMES IRY
Stateless paradigm
JEE Session Facade stack trace
Functions …



F1(F2(F3(F4(Xinput))))
Jump to Scala
Few syntax details to understand examples
val, List


val act1 = List ("Leonardo" , "Raphael")
List operations, Nil


val act2 = “April” :: "Donatello" :: Nil
val act3 = act1 ::: act2
Var, no sugar


var act4:List[String] = act3
act4 = "Michelangelo" :: act4
Function


(x: Int) => x * 2
Function as value


val double = (x: Int) => x * 2
double(10)
Sugar
List(1,2,3).foreach ( (x:Int) => println ( x ) )
List(1,2,3).foreach ( x => println ( x ) )
List(1,2,3).foreach ( println _ )
List(1,2,3).foreach ( println )
Yield
val result = for (i <- 1 to 5) yield i

Vector(1, 2, 3, 4, 5)
Trait
trait Manager extends Lead{
  private var workSchedule:Schedule = …
  override def schedule = workSchedule
}

class College extends Worker with Manager with
Wellpaid with HardToFind
1. Monads are Container Types




        Option, List, …
Where is my manager?

Company company = getCompany();
Manager manager = company.findManager();

if (manager != null) {
   manager.getBonusFor(me);
} else {
   System.out.println("As always...");
}
Schrödinger's State
public interface Option<T> {
    public T value();
    public boolean hasValue();
}

Company company = getCompany();
Option<Manager> manager = company.findManager();

if (manager.hasValue()) {
   manager.getBonusFor(me);
} else {
   System.out.println(”Aren't news!");
}
Option
trait Manager {
  def getBonusFor(id: Long) :Option[Double]
}

trait Company {
  def manager:Manager
}

val sum = getCompany().manager. getBonusFor(myId)
val bonus = sum match {
  case Some(bonus) => bonus
  case None => 0
}
0 on default

val myBonus = manager.getOrElse(0)
0 on default

val myBonus = manager.getOrElse(0)
If in If
Company company = getCompany();
   if (company != null) {
      Manager manager = company.findManager();

       if (manager != null) {
          double bonus = manager.getBonusFor(me);

          ...
       } else {
          System.out.println("Isn't news!");
       }
   }
Or Else
val m =
company.getManager.getOrElse(ManagmentFac
tory.newOne)
m.getBonusFor(me).getOrElse(…)
Option is a monad
for (
  c <- getCompany;
  m <- c.getManagerFor(me);
  b <- m.getBonusFor(me)
) b spend
2. Monads Support Higher Order
              Functions
val list = List(1, 2, 3)
def neg (elem: Int) = -elem
val mapResult = list map neg



List(1,2,3) map {-_}
Doesn’t change the kind of monad, but
may change its parameterized type...
val one = Some(1)
val oneString = one map {_.toString}
assert (oneString == Some("1"))
3. Monads are Combinable
val opMan : Option[Manager] = company
getManager
def extractBonus(m:Manager) : Option[Double]
= ...
val result = opMan map extractBonus

Option[Option[Double]]
List[List[Int]]]

List[List[List[Int]]]]
Flatten
def flatten[A]
(outer:Option[Option[A]]) : Option[A] =
  outer match {
    case None => None
    case Some(inner) => inner
  }

If the outer option is None, then result is None.
Otherwise the result is the inner Option.
Join, Flatten etc
Scala does not require you to write flatten explicitly.
But it does require that each monad have a method
called flatMap.

class M[A] {
  private def flatten[B](x:M[M[B]]) : M[B] = ...
  def map[B](f: A => B) : M[B] = ...
  def flatMap[B](f: A => M[B]) : M[B] = flatten(map(f))
}
Review
val opMan : Option[Manager] = company
getManager
def extractBonus(m:Manager) : Option[Double]
= ...
val result = opMan flatMap extractBonus



Option[Double]
4. Monads Can Be Built In Different
             Ways
   ”unit,” in Haskell it's called “return”

single argument “constructor” or ”actory”


    A become a monad of type M[A]
       For List: unit(x) == List(x)
       For Option: unit(x) == Some(x)
class M[A](value: A) {
  private def unit[B] (value : B) = new M(value)
   …
}
Map based on flatMap
Scala does not require a separate "unit" function or
method

class M[A](value: A) {
  private def unit[B] (value : B) = new M(value)
  def map[B](f: A => B) : M[B] =
       flatMap {x => unit(f(x))}
  def flatMap[B](f: A => M[B]) : M[B] = ...
}
Basis 1
Generic    Haskell                   Scala
M          data M a                  class M[A]
           or newtype M a            or case class M[A]
           or instance Monad (M a)   or trait M[A]

Ma         Ma                        M[A]
unit v     return v                  new M(v)
                                     or M(v)

map f m    fmap f m                  m map f
bind f m   m >>= f                   m flatMap f
           or f =<< m
join       join                      flatten
           do                        for

Introduction to Monads in Scala (1)

  • 1.
    Monads Part 1 functional programming with scala
  • 2.
    Where r theverbs lost?
  • 3.
    Thinking in UseCases  get the coffee  meet with colleagues on the kitchen  read emails  review social media  update the workspace  write the code
  • 4.
    Thinking in Java CompanyHolder.getStuffFactoryBuilder(). buildCurrentState(). find(Rooms.KITCHEN, CoffeMachine.Any). get(0). run(new CoffeeJob( me.getHabitsStore().find("coffe"). mapToJobMachnie(), null));
  • 5.
    Thinking in Java Needan update: new SVNUpdateJob(myProject).go(); • execute • process • run • start • doIt
  • 6.
    Thinking in Java CheckGmail MySmartProxyHack.go(); go via Hack or Job – action name isn't important
  • 7.
    Q How many timesu were not lucky with fact that do is the keyword? ProjectManager.do() vs manage SecurityProcessor.do() vs process
  • 8.
    Guava from G Badlibrary: it makes me feeling smell Preconditions.checkArgument(...) vs checkArgument(...) with static import... but this is a way for nonlazy dudes in Java
  • 9.
    Patriots in Java Firstaction is create, get, find, build, ...? Use a Spring, Guice!!!
  • 10.
    Other ways ofthinking C and C++ Python
  • 11.
    Evil? We r smart– look into Python, Ruby, Java Script or Perl – gun meat. Im smart enough to understand AbstractProxyMediator or NotificationStrategyFactory – they even don't have it!
  • 12.
  • 13.
    Monad is Usually articlesthat start with words like "monad" and "functor" quickly devolve into soup of Greek letters. That's because both are abstract concepts in a branch of mathematics called category theory and explaining them completely is a mathematical exercise. JAMES IRY
  • 14.
  • 15.
    JEE Session Facadestack trace
  • 16.
  • 17.
    Jump to Scala Fewsyntax details to understand examples
  • 18.
    val, List val act1= List ("Leonardo" , "Raphael")
  • 19.
    List operations, Nil valact2 = “April” :: "Donatello" :: Nil val act3 = act1 ::: act2
  • 20.
    Var, no sugar varact4:List[String] = act3 act4 = "Michelangelo" :: act4
  • 21.
  • 22.
    Function as value valdouble = (x: Int) => x * 2 double(10)
  • 23.
    Sugar List(1,2,3).foreach ( (x:Int)=> println ( x ) ) List(1,2,3).foreach ( x => println ( x ) ) List(1,2,3).foreach ( println _ ) List(1,2,3).foreach ( println )
  • 24.
    Yield val result =for (i <- 1 to 5) yield i Vector(1, 2, 3, 4, 5)
  • 25.
    Trait trait Manager extendsLead{ private var workSchedule:Schedule = … override def schedule = workSchedule } class College extends Worker with Manager with Wellpaid with HardToFind
  • 26.
    1. Monads areContainer Types Option, List, …
  • 27.
    Where is mymanager? Company company = getCompany(); Manager manager = company.findManager(); if (manager != null) { manager.getBonusFor(me); } else { System.out.println("As always..."); }
  • 28.
    Schrödinger's State public interfaceOption<T> { public T value(); public boolean hasValue(); } Company company = getCompany(); Option<Manager> manager = company.findManager(); if (manager.hasValue()) { manager.getBonusFor(me); } else { System.out.println(”Aren't news!"); }
  • 29.
    Option trait Manager { def getBonusFor(id: Long) :Option[Double] } trait Company { def manager:Manager } val sum = getCompany().manager. getBonusFor(myId) val bonus = sum match { case Some(bonus) => bonus case None => 0 }
  • 30.
    0 on default valmyBonus = manager.getOrElse(0)
  • 31.
    0 on default valmyBonus = manager.getOrElse(0)
  • 32.
    If in If Companycompany = getCompany(); if (company != null) { Manager manager = company.findManager(); if (manager != null) { double bonus = manager.getBonusFor(me); ... } else { System.out.println("Isn't news!"); } }
  • 33.
    Or Else val m= company.getManager.getOrElse(ManagmentFac tory.newOne) m.getBonusFor(me).getOrElse(…)
  • 34.
    Option is amonad for ( c <- getCompany; m <- c.getManagerFor(me); b <- m.getBonusFor(me) ) b spend
  • 35.
    2. Monads SupportHigher Order Functions val list = List(1, 2, 3) def neg (elem: Int) = -elem val mapResult = list map neg List(1,2,3) map {-_}
  • 36.
    Doesn’t change thekind of monad, but may change its parameterized type... val one = Some(1) val oneString = one map {_.toString} assert (oneString == Some("1"))
  • 37.
    3. Monads areCombinable val opMan : Option[Manager] = company getManager def extractBonus(m:Manager) : Option[Double] = ... val result = opMan map extractBonus Option[Option[Double]]
  • 38.
  • 39.
    Flatten def flatten[A] (outer:Option[Option[A]]) :Option[A] = outer match { case None => None case Some(inner) => inner } If the outer option is None, then result is None. Otherwise the result is the inner Option.
  • 40.
    Join, Flatten etc Scaladoes not require you to write flatten explicitly. But it does require that each monad have a method called flatMap. class M[A] { private def flatten[B](x:M[M[B]]) : M[B] = ... def map[B](f: A => B) : M[B] = ... def flatMap[B](f: A => M[B]) : M[B] = flatten(map(f)) }
  • 41.
    Review val opMan :Option[Manager] = company getManager def extractBonus(m:Manager) : Option[Double] = ... val result = opMan flatMap extractBonus Option[Double]
  • 42.
    4. Monads CanBe Built In Different Ways ”unit,” in Haskell it's called “return” single argument “constructor” or ”actory” A become a monad of type M[A] For List: unit(x) == List(x) For Option: unit(x) == Some(x)
  • 43.
    class M[A](value: A){ private def unit[B] (value : B) = new M(value) … }
  • 44.
    Map based onflatMap Scala does not require a separate "unit" function or method class M[A](value: A) { private def unit[B] (value : B) = new M(value) def map[B](f: A => B) : M[B] = flatMap {x => unit(f(x))} def flatMap[B](f: A => M[B]) : M[B] = ... }
  • 45.
    Basis 1 Generic Haskell Scala M data M a class M[A] or newtype M a or case class M[A] or instance Monad (M a) or trait M[A] Ma Ma M[A] unit v return v new M(v) or M(v) map f m fmap f m m map f bind f m m >>= f m flatMap f or f =<< m join join flatten do for

Editor's Notes