Scala for Jedi
- 5. OPTION
val set = Set(42, null, "Yoda")
val found = set find { _ == null }
if (found != null) {
// huh, we've found it or not?
println(s"Found $found!")
} else {
println("Not found.")
}
- 6. OPTION
val set = Set(42, null, "Yoda")
val found = set find { _ == null }
found match {
case Some(elem) => println(s"Found $elem!")
case None => println("Not found.")
}
olation
2 .10
string interp
- 7. TYPES ON STEROIDS
sealed abstract class Option[+A] {
def get: A
}
final case class Some[+A](x: A) extends Option[A] {
def get = x
}
case object None extends Option[Nothing] {
def get = throw new NoSuchElementException("None.get")
}
- 8. TYPE COVARIANCE
not im 2 .10
pleme
class Cell[T](x: T) { nte d
def get: T = ???
def set(x: T) { ??? }
}
val c1 = new Cell[String]("Anakin")
val c2: Cell[Any] = c1 // type mismatch
- 10. TYPE COVARIANCE
class Cell[+T](x: T) {
def get: T = ???
def set(x: T) { ??? } // compilation error
}
val c1 = new Cell[String]("Anakin")
val c2: Cell[Any] = c1
c2.set(37)
- 11. TYPE COVARIANCE
class Cell[-T](x: T) {
def get: T = ??? // compilation error
def set(x: T) { ??? }
}
val c1 = new Cell[Any](37)
val c2: Cell[String] = c1
val jedi = c2.get
- 13. LOWER & UPPER BOUNDS
class List[+A] {
def ++[B >: A](that: List[B]): List[B] = ???
}
val strs = List("Leia", "Organa")
val syms = List('Anakin, 'Skywalker)
val all = strs ++ syms // List[java.io.Serializable]
def max[A <: Ordered[_]](xs: List[A]): A = ???
val accounts: List[Money]
max(accounts)
- 14. CONTEXT BOUNDS
trait Jedi { def force: Double }
val jediOrder: Set[Jedi]
val grandMaster = jediOrder.max
// No implicit Ordering defined for Jedi.
implicit val jediOrdering = new Ordering[Jedi] {
def compare(j1: Jedi, j2: Jedi) = j1.force.compare(j2.force)
}
val grandMaster = jediOrder.max
trait TraversableOnce[+A] {
def max[B >: A](implicit cmp: Ordering[B]): A = ???
def max[A : Ordering]: A = ???
}
- 15. TYPES HIERARCHY
Any
AnyVal AnyRef/Object
ScalaObject
Value classes Primitives Java classes
2.10 Scala classes
Null
Nothing
- 16. TYPES ON STEROIDS
sealed abstract class Option[+A] {
def get: A
}
final case class Some[+A](x: A) extends Option[A] {
def get = x
}
case object None extends Option[Nothing] {
def get = throw new NoSuchElementException("None.get")
}
- 18. PARALLEL COLLECTIONS
val nums = (1 to 10).par
nums foreach { x => print(x + " ") }
// 1 2 8 9 10 7 5 6 3 4
nums reduce { _ - _ }
// -15
nums reduce { _ - _ }
// 5
nums reduce { _ + _ }
// 55
val word = Seq("G", "r", "i", "e", "v", "o", "u", "s")
word.par reduce { _ ++ _ }
// Grievous
- 19. 2.10
FUTURES
• Хранилище для значения, которое будет получено в
будущем
• Получениезначения может быть выполнено асинхронно и
не блокировать программу
• Значение может быть не получено вовсе
- 20. FUTURES
val f: Future[List[String]] = future {
session.getRecentPosts
}
f onSuccess {
case posts =>
for (post <- posts) println(post)
}
f onFailure {
case t =>
println("An error has occured: " + t.getMessage)
}
- 22. FOR
def fileLines(f: File): Seq[String] = ???
for (file <- files) {
if (!file.getName.startsWith(".")) {
for (line <- fileLines(file)) {
if (line.nonEmpty) {
println(file + ": " + line)
}
}
}
}
- 23. FOR
for {
file <- files
if !file.getName.startsWith(".")
line <- fileLines(file)
if line.nonEmpty
} println(file + ": " + line)
files withFilter { !_.getName.startsWith(".") } foreach { file =>
fileLines withFilter { _.nonEmpty } foreach { line =>
println(file + ": " + line)
}
}
- 24. FOR
val lines = for {
file <- files
if !file.getName.startsWith(".")
line <- fileLines(file)
if line.nonEmpty
} yield (file + ": " + line)
files withFilter { !_.getName.startsWith(".") } flatMap { file =>
fileLines(file) withFilter { _.nonEmpty } map { line =>
file + ": " + line
}
}
- 25. FUTURES
val usdQuote = future { connection.getCurrentValue(USD) }
val chfQuote = future { connection.getCurrentValue(CHF) }
val purchase = for {
usd <- usdQuote
chf <- chfQuote
if isProfitable(usd, chf)
} yield connection.buy(amount, chf)
purchase onSuccess {
case _ => println(s"Purchased $amount CHF")
}
- 26. FUTURES
val rateQuote = future {
connection.getCurrentValue(USD)
}
val purchase = rateQuote map { quote =>
if (isProfitable(quote)) connection.buy(amount, quote)
else throw new Exception("not profitable")
}
purchase onSuccess {
case _ => println(s"Purchased $amount USD")
}
filter, fallbackTo, recoverWith, andThen, …
- 27. PROMISES
val p = promise[T]
val f = p.future
val producer = future {
val r = produceSomething()
p success r
continueDoingSomethingUnrelated()
}
val consumer = future {
startDoingSomething()
f onSuccess {
case r => doSomethingWithResult()
}
}
- 28. PROMISES
def first[T](f: Future[T], g: Future[T]): Future[T] = {
val p = promise[T]
f onSuccess {
case x => p.tryComplete(x)
}
g onSuccess {
case x => p.tryComplete(x)
}
p.future
}
- 29. 2.10
ACTORS & AKKA
• Акторы – это приватные данные и описание поведения
• Общение между акторами только через сообщения с
неизменяемыми данными
• Акторы могут создавать других акторов и управлять ими в
случае исключительных ситуаций
- 30. ACTORS
class MyActor extends Actor {
def receive = {
case "test" => log("received test")
case _ => log("received unknown message")
}
}
object Main extends App {
val system = ActorSystem("MySystem")
val myActor = system.actorOf(Props[MyActor], name = "myactor")
myActor ! "test"
}
- 31. ACTORS
class Squarer extends Actor {
def receive = {
case x: Int => sender ! (x * x)
case x: Double => sender ! (x * x)
}
}
class Mathematician extends Actor {
val squarer = context.actorOf(Props[Squarer], name = "squarer")
def receive = {
case x: Int =>
(squarer ? x) onComplete {
case Success(x) => log(x)
case Failure => fail()
}
}
}
- 33. {
on[ A] =
ti
n)) : Op
ea trait
=> Bool Provi
, p : (A def s der {
rec Lis t[A] }
mth:
Int
@ tail A]( xs:
f ind[ p)
def tch
{
ne (ta il,
x s ma l = > No => find class
e Ni tail lse LazyO
c as :: hea d) e lazy ne ex
tends
head ) S ome( val s Provi
case ead) ??? mth = der {
p(h {
if ( }
} }
}
assert(assertion: Boolean, message: => Any): Unit
assert(true, { ??? })
assert(false, { ??? })
?
my t = ??
2.10 age : In ?
pack o o { v al x t = ??
implicit
class Ro cla ss F e[this] y : In = ???
ckString vat val nt
def rock
() = ??? (str: St
ring) { pri e[ Foo] al z: I
} pr ivat [my] v
e
"foo".ro pr ivat
ck()
}
val xml = <and><much>More!</much></and>