6. Функциональные структуры данных,
отсутствующие в Scala stdlib:
scalaz./[A, B] Правильный Either
scalaz.&/[A, B] Как Either, но может быть
одновременно и A, и B
scalaz.Either3[A, B, C] Как Either, но может быть
A, B или C
7. В ООП доминирует подтиповой
полиморфизм:
class Int {
def <(other: Int): Boolean = …
}
class Double {
def <(other: Double): Boolean = …
}
class String {
def <(other: String): Boolean = …
}
8. В ООП доминирует подтиповой
полиморфизм:
class Int {
def <(other: Int): Boolean = …
}
class Double {
def <(other: Double): Boolean = …
}
class String {
def <(other: String): Boolean = …
}
9. Общее поведение выделяется в
класс:
trait Ordered[A] {
def <(other: A): Boolean
…
}
class Int extends Ordered[Int] { … }
class Double extends Ordered[Double] { … }
class String extends Ordered[String] { … }
10. Проблема 1: не можем заранее
предугадать, какое поведение нам
понадобится:
class Int extends Ordered[Int]
with Addable[Int]
with Random[Int]
with ToJSON[Int]
with ToXML[Int]
with ToBinary[Int]
with …
11. Проблема 2: не всё общее
поведение можно выразить через
наследование
trait Zero[A] {
def zero: A
}
class Int extends Zero[Int] {
def zero = 0
}
Чтобы иметь возможность вызвать zero,
нужен экземпляр класса Int
???
19. scalaz.Order[A]
trait Order[A] extends Equal[A] {
def order(a1: A, a2: A): Ordering
def equal(a1: A, a2: A) =
order(a1, a2) == EQ
}
sealed trait Ordering
case object LT extends Ordering
case object EQ extends Ordering
case object GT extends Ordering
20. Принцип использования Scalaz:
Когда объявляем класс
class Rational(nom: Int, denom: Int) { … }
… в объекте-компаньоне создаём инстанс,
реализующий все необходимые классы типов:
object Rational {
implicit object instance
extends Order[Rational]
with Numeric[Rational]
with … {
def order(r1: Rational, r2: Rational) = …
…
}
}
21. scalaz.Enum[A]
trait Enum[A] extends Order[A] {
def succ(a: A): A
def pred(a: A): A
def fromToL(f: A, t: A): List[A] = …
}
implicit class EnumOps[A](a: A)
(implicit val e: Enum[A]) {
def |-> (to: A) = e.fromToL(a, to)
}
32. trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
implicit object listInstance =
new Functor[List] {
def map[A,B](fa: List[A])(f: A => B) =
fa.map(f)
}
33. val opt: Option[Int] = for {
i ← Some(2)
j ← Some(3)
} yield (i + j)
val list: List[(Int, Int)] = for {
i ← List(1,2,3)
j ← List(5,6)
} yield (i, j)
34. val opt: Option[Int] = for {
i ← Some(2)
j ← Some(3)
} yield (i + j)
val list: List[(Int, Int)] = for {
i ← List(1,2,3)
j ← List(5,6)
} yield (i, j)