Przemysław Piotrowski
@ppiotrow
Codepot 2015
for {
x <- List(1,2,3..10)
y = x * x
if y < 9
} yield y //List(1,2)generator
guard
definition
set-builder notation
T1.0
Task to do
class M[A] {
def map[B](f: A => B): M[B]
def flatMap[B](f: A => M[B]): M[B]
def filter(p: M => Boolean): M[A]
}
val a: Option[Int] = Some(1)
val b: Option[Int] = None
a.map(_ * 2) //Some(2)
b.map(_ * 2) //None
//def flatMap[B](f: A => Option[B]): Option[B]
a.flatMap{ value => Some(value * 2)} //Some(2)
a.foreach(println) //> "1"T2.[0-3]
T3.[0-2]
for {
i <- List(1,2,3,4)
} yield i*2List(1,2,3,4)
.map(i => i*2)for {
i <- List(1,2,3,4)
if i % 2 == 0
} yield iList(1,2,3,4)
.withFilter(i=>i%2==0)for {
i <- List(1,2,3,4)
} print(i*2)List(1,2,3,4)
.foreach(i => i*2)T3.3
http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#for-comprehensions-and-for-loops
val input: Try[Int] = Try(StdIn.readLine("Number: ").toInt)
val result: Try[Int] = i.map(123/_)
result match {
case Success(x) => print(s"Result is $x")
case Failure(_) => print("Please try again")
}T4.[0-3]
val accBalance = Future {
Thread.sleep(10*1000)
5}
val newAccBalance = accBalance.map(_ * 1.035)
newAccBalance
.recover{case ex: Exception => MILION }
.onSuccess{balance => println(balance)}
//def onComplete[U](f: Try[T] => U): Unit
for {
i <- Future.successful(1)
} yield i * 3T5.[0-5]
def espresso(water: Water, beans: Beans): Either[String, Espresso]={
if (water.temperature < 93)
Left("Water too cold")
else if (!beans.kind.equals("Robusta"))
Left("Wrong type of beans")
else
Right(Espresso())
}
val coffee = espresso(water,beans)
coffee match {
case Left(errorMsg) => displayError(errorMsg)
case Right(espresso) => drink(espresso)
}
val result: Either[Alert, Espresso] = coffee.right
.map(coffee.sweeten)
.left
.map(Alert _)Tiramisu with validation
T6.0
Some(1).map{i =>
val j = i+1
(i, j)
}.map( case (i, j) => j)for {
i <- Some(1)
j = i + 1
} yield jCoffeeMachine.espresso(water, beans).right.map{ espresso =>
val espressoSweeten = espresso.sweeten
(espresso, espressoSweeten)
}.map(case(e, s) => s)for {
espresso <- CoffeeMachine.espresso(water, beans).right
sweeten = espresso.sweeten
} yield sweetenT6.[1-3]
No .map() on Either
do we always need same 'shape'?
def flatMap
class M[A] {
def flatMap[B](f: A => M[B]): M[B]
...
def foreach(f: A => Unit)
}T7.1
val someFuture = Future.successful(1)
val someOption = Option(1)
for {
a <- someFuture
} yield for {
b <- someOption
} yield a + b//sigle generator
for(a <- generator) yield a + 1
//multiple generators in parentheses
for(a <- generator; if a >3; b <- gen2)
yield a + bOpinon
List, Option, Future, Either, Try - good for daily work
for-comprehension syntax make work with containers easy and declarative.
refactoring
code is readable
Przemysław Piotrowski
@ppiotrow
Codepot 2015