introduction to monads in scala (1)

Post on 07-May-2015

8.353 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

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