introduction to monads in scala (1)
Post on 07-May-2015
8.351 Views
Preview:
TRANSCRIPT
Monads
Part 1functional 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 manageSecurityProcessor.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" :: Nilval act3 = act1 ::: act2
Var, no sugar
var act4:List[String] = act3act4 = "Michelangelo" :: act4
Function
(x: Int) => x * 2
Function as value
val double = (x: Int) => x * 2double(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..."); } Java
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!"); } Java
Optiontrait 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} Sc
ala
0 on default
val myBonus = manager.getOrElse(0)
Scala
0 on default
val myBonus = manager.getOrElse(0)
Scala
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!"); } } Java
Or Else
val m = company.getManager.getOrElse(ManagmentFactory.newOne)m.getBonusFor(me).getOrElse(…)
Scala
Option is a monad
for ( c <- getCompany; m <- c.getManagerFor(me); b <- m.getBonusFor(me)) b spend
Scala
2. Monads Support Higher Order Functions
val list = List(1, 2, 3)def neg (elem: Int) = -elemval mapResult = list map neg
List(1,2,3) map {-_}
Scala
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"))
Scala
3. Monads are Combinable
val opMan : Option[Manager] = company getManagerdef extractBonus(m:Manager) : Option[Double] = ...val result = opMan map extractBonus
Option[Option[Double]]
Scala
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.
Scala
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))}
Scala
Review
val opMan : Option[Manager] = company getManagerdef extractBonus(m:Manager) : Option[Double] = ...val result = opMan flatMap extractBonus
Option[Double]
Scala
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)
Scala
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] = ...}
Scala
Basis 1Generic Haskell Scala
M data M a or newtype M a or instance Monad (M a)
class M[A]or case class M[A]or trait M[A]
M a M a 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 >>= for f =<< m
m flatMap f
join join flatten
do for
top related