Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Введение в
Scalaz
http://lambdansk.org
https://twitter.com/ZhekaKozlov
Scalaz – библиотека, которая
приносит концепции Haskell в
Scala
Проекты, использующие Scalaz:
• https://github.com/argonaut-io/argonaut/
• https://github.com/tpolecat/doobie
• https://gi...
Функциональные структуры данных,
отсутствующие в Scala stdlib:
scalaz.NonEmptyList[A] Непустой список
scalaz.EphemeralStre...
FingerTree[Int, A] Vector[A] TreeMap[Int, A] List[A]
head O(1) O(log32 n) O(log n) O(1)
tail O(1) O(log32 n) O(log n) O(1)...
Функциональные структуры данных,
отсутствующие в Scala stdlib:
scalaz./[A, B] Правильный Either
scalaz.&/[A, B] Как Either...
В ООП доминирует подтиповой
полиморфизм:
class Int {
def <(other: Int): Boolean = …
}
class Double {
def <(other: Double):...
В ООП доминирует подтиповой
полиморфизм:
class Int {
def <(other: Int): Boolean = …
}
class Double {
def <(other: Double):...
Общее поведение выделяется в
класс:
trait Ordered[A] {
def <(other: A): Boolean
…
}
class Int extends Ordered[Int] { … }
c...
Проблема 1: не можем заранее
предугадать, какое поведение нам
понадобится:
class Int extends Ordered[Int]
with Addable[Int...
Проблема 2: не всё общее
поведение можно выразить через
наследование
trait Zero[A] {
def zero: A
}
class Int extends Zero[...
Решение: классы типов
trait Addable[A] {
def add(a1: A, a2: A): A
}
trait Zero[A] {
def zero: A
}
Решение: классы типов
object intInstance
extends Addable[Int]
with Zero[Int] {
def add(a1: Int, a2: Int) = a1+a2
def zero ...
scala> intInstance.add(3, 5)
res0: Int = 8
scala> stringInstance.zero
res1: String = ""
scalaz.Equal[A]
trait Equal[A] {
def equal(a1: A, a2: A): Boolean
}
scala> intInstance.equal(3, 3)
res0: Boolean = true
scala> stringInstance.equal("s", "s2")
res1: Boolean = false
Добавим синтаксического сахару:
implicit class EqualOps[A](a: A)
(implicit val e: Equal[A]) {
def ===(other: A) = e.equal(...
scala> 3 === 3
res0: Boolean = true
scala> "s" /== "s2"
res1: Boolean = true
scala> 3 === "s"
<console>:14: error: type mi...
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...
Принцип использования Scalaz:
Когда объявляем класс
class Rational(nom: Int, denom: Int) { … }
… в объекте-компаньоне созд...
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] = …
}...
scala> 1 |-> 5
res0: List[Int] = List(1, 2, 3, 4, 5)
scala> 'a' |-> 'd'
res1: List[Char] = List(a, b, c, d)
scalaz.Semigroup[A]
trait Semigroup [A] {
def append(a1: A, a2: => A): A
}
implicit class SemigroupOps[A](a: A)
(implicit ...
scala> 3 |+| 2
res0: Int = 5
scala> List(1,2,3) |+| List(4,5)
res1: List[Int] = List(1, 2, 3, 4, 5)
scala> "abc" |+| "de"
...
scala> List(1,2,3) ++ "ab"
res0: List[AnyVal] = List(1, 2, 3, a, b)
scala> List(1,2,3) |+| "ab"
<console>:26: error: type ...
scalaz.Monoid[A]
trait Monoid [A] extends Semigroup [A] {
def zero: A
}
def sum[A](list: List[A])
(implicit m: Monoid[A]) =
list.foldLeft(m.zero)(_ |+| _)
scala> sum(List(1,2,3))
res0: Int = 6
scala> sum(List("ab","cd","ef"))
res1: String = abcdef
scala> sum(List(List(1,2),Lis...
class List[A] {
def map[B](f: A => B): List[B]
}
class Vector[A] {
def map[B](f: A => B): Vector[B]
}
class Option[A] {
de...
class List[A] {
def map[B](f: A => B): List[B]
}
class Vector[A] {
def map[B](f: A => B): Vector[B]
}
class Option[A] {
de...
scalaz.Functor[F[_]]
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
Конструктор типа
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
implicit object listInstance =
new Functor[List] {
def map...
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 ...
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 ...
trait Apply[F[_]] extends Functor[F] {
def apply2[A,B,C](fa: => F[A], fb: => F[B])
(f: (A,B) => C): F[C]
}
scalaz.Apply[F[...
scala> Apply[Option].apply2(x, y)(_ + _)
res0: Option[Int] = Some(5)
scala> Apply[List].apply2(List(1,2,3),
List(5,6))((_,...
val opt: Option[Int] = Some(5)
val list: List[String] = List("a")
val fut: Future[Double] = Future(3.5)
val opt: Option[Int] = Some(5)
val list: List[String] = List("a")
val fut: Future[Double] = Future(3.5)
trait Pure[F[_]] {
def point[A](a: => A): F[A]
}
scalaz.Pure[F[_]]
Был удалён в Scalaz 7
trait Applicative[F[_]] extends Apply[F] {
def point[A](a: => A): F[A]
}
scalaz.Applicative[F[_]]
class List[A] {
def flatMap[B](f: A => List[B]): List[B]
}
class Vector[A] {
def flatMap[B](f: A => Vector[B]): Vector[B]
...
scalaz.Bind[F[_]]
trait Bind[F[_]] extends Apply[F] {
def bind[A,B](fa: F[A])
(f: A => F[B]): F[B]
}
scala> some(some(5)).join
res0: Option[Int] = Some(5)
scala> List(List(1,2), List(3,4,5)).join
res1: List[Int] = List(1,2,...
scalaz.Monad[F[_]]
trait Monad[F[_]]
extends Applicative[F]
with Bind[F] {
…
}
Введение в Scalaz
Prochain SlideShare
Chargement dans…5
×
Prochain SlideShare
Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13
Suivant
Télécharger pour lire hors ligne et voir en mode plein écran

2

Partager

Télécharger pour lire hors ligne

Введение в Scalaz

Télécharger pour lire hors ligne

Введение в Scalaz. Видео: http://www.youtube.com/watch?v=XXNdT83H89o

Livres associés

Gratuit avec un essai de 30 jours de Scribd

Tout voir

Введение в Scalaz

  1. 1. Введение в Scalaz http://lambdansk.org https://twitter.com/ZhekaKozlov
  2. 2. Scalaz – библиотека, которая приносит концепции Haskell в Scala
  3. 3. Проекты, использующие Scalaz: • https://github.com/argonaut-io/argonaut/ • https://github.com/tpolecat/doobie • https://github.com/oncue/remotely • https://github.com/scalaz/scalaz-stream • https://github.com/xuwei-k/httpz • https://github.com/http4s/http4s
  4. 4. Функциональные структуры данных, отсутствующие в Scala stdlib: scalaz.NonEmptyList[A] Непустой список scalaz.EphemeralStream[A] Правильный Stream (аналог списков в Haskell) scalaz.FingerTree[V, A] http://staff.city.ac.uk/~ross /papers/FingerTree.html scalaz.DList[A] Чистофункциональный аналог ListBuffer
  5. 5. FingerTree[Int, A] Vector[A] TreeMap[Int, A] List[A] head O(1) O(log32 n) O(log n) O(1) tail O(1) O(log32 n) O(log n) O(1) last O(1) O(log32 n) O(log n) O(n) init O(1) O(log32 n) O(log n) O(n) get(index) O(log n) O(log32 n) O(log n) O(n)
  6. 6. Функциональные структуры данных, отсутствующие в Scala stdlib: scalaz./[A, B] Правильный Either scalaz.&/[A, B] Как Either, но может быть одновременно и A, и B scalaz.Either3[A, B, C] Как Either, но может быть A, B или C
  7. 7. В ООП доминирует подтиповой полиморфизм: class Int { def <(other: Int): Boolean = … } class Double { def <(other: Double): Boolean = … } class String { def <(other: String): Boolean = … }
  8. 8. В ООП доминирует подтиповой полиморфизм: class Int { def <(other: Int): Boolean = … } class Double { def <(other: Double): Boolean = … } class String { def <(other: String): Boolean = … }
  9. 9. Общее поведение выделяется в класс: trait Ordered[A] { def <(other: A): Boolean … } class Int extends Ordered[Int] { … } class Double extends Ordered[Double] { … } class String extends Ordered[String] { … }
  10. 10. Проблема 1: не можем заранее предугадать, какое поведение нам понадобится: class Int extends Ordered[Int] with Addable[Int] with Random[Int] with ToJSON[Int] with ToXML[Int] with ToBinary[Int] with …
  11. 11. Проблема 2: не всё общее поведение можно выразить через наследование trait Zero[A] { def zero: A } class Int extends Zero[Int] { def zero = 0 } Чтобы иметь возможность вызвать zero, нужен экземпляр класса Int ???
  12. 12. Решение: классы типов trait Addable[A] { def add(a1: A, a2: A): A } trait Zero[A] { def zero: A }
  13. 13. Решение: классы типов object intInstance extends Addable[Int] with Zero[Int] { def add(a1: Int, a2: Int) = a1+a2 def zero = 0 } object stringInstance extends Addable[String] with Zero[String] { def add(s1: String, s2: String) = s1+s2 def zero = "" }
  14. 14. scala> intInstance.add(3, 5) res0: Int = 8 scala> stringInstance.zero res1: String = ""
  15. 15. scalaz.Equal[A] trait Equal[A] { def equal(a1: A, a2: A): Boolean }
  16. 16. scala> intInstance.equal(3, 3) res0: Boolean = true scala> stringInstance.equal("s", "s2") res1: Boolean = false
  17. 17. Добавим синтаксического сахару: implicit class EqualOps[A](a: A) (implicit val e: Equal[A]) { def ===(other: A) = e.equal(a, other) def /==(other: A) = !e.equal(a, other) }
  18. 18. scala> 3 === 3 res0: Boolean = true scala> "s" /== "s2" res1: Boolean = true scala> 3 === "s" <console>:14: error: type mismatch; found : String("s") required: Int 3 === "s" ^
  19. 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. 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. 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) }
  22. 22. scala> 1 |-> 5 res0: List[Int] = List(1, 2, 3, 4, 5) scala> 'a' |-> 'd' res1: List[Char] = List(a, b, c, d)
  23. 23. scalaz.Semigroup[A] trait Semigroup [A] { def append(a1: A, a2: => A): A } implicit class SemigroupOps[A](a: A) (implicit val s: Semigroup[A]) { def |+| (o: => A) = s.append(a, o) }
  24. 24. scala> 3 |+| 2 res0: Int = 5 scala> List(1,2,3) |+| List(4,5) res1: List[Int] = List(1, 2, 3, 4, 5) scala> "abc" |+| "de" res2: String = abcde
  25. 25. scala> List(1,2,3) ++ "ab" res0: List[AnyVal] = List(1, 2, 3, a, b) scala> List(1,2,3) |+| "ab" <console>:26: error: type mismatch; found : String("ab") required: List[Int] List(1,2,3) |+| "ab" ^
  26. 26. scalaz.Monoid[A] trait Monoid [A] extends Semigroup [A] { def zero: A }
  27. 27. def sum[A](list: List[A]) (implicit m: Monoid[A]) = list.foldLeft(m.zero)(_ |+| _)
  28. 28. scala> sum(List(1,2,3)) res0: Int = 6 scala> sum(List("ab","cd","ef")) res1: String = abcdef scala> sum(List(List(1,2),List(3,4)) res2: List[Int] = List(1,2,3,4)
  29. 29. class List[A] { def map[B](f: A => B): List[B] } class Vector[A] { def map[B](f: A => B): Vector[B] } class Option[A] { def map[B](f: A => B): Option[B] }
  30. 30. class List[A] { def map[B](f: A => B): List[B] } class Vector[A] { def map[B](f: A => B): Vector[B] } class Option[A] { def map[B](f: A => B): Option[B] }
  31. 31. scalaz.Functor[F[_]] trait Functor[F[_]] { def map[A,B](fa: F[A])(f: A => B): F[B] } Конструктор типа
  32. 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. 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. 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)
  35. 35. trait Apply[F[_]] extends Functor[F] { def apply2[A,B,C](fa: => F[A], fb: => F[B]) (f: (A,B) => C): F[C] } scalaz.Apply[F[_]]
  36. 36. scala> Apply[Option].apply2(x, y)(_ + _) res0: Option[Int] = Some(5) scala> Apply[List].apply2(List(1,2,3), List(5,6))((_, _)) res1: List[(Int,Int)] = List((1,5),(1,6), (2,5),(2,6),(3,5),(3,6))
  37. 37. val opt: Option[Int] = Some(5) val list: List[String] = List("a") val fut: Future[Double] = Future(3.5)
  38. 38. val opt: Option[Int] = Some(5) val list: List[String] = List("a") val fut: Future[Double] = Future(3.5)
  39. 39. trait Pure[F[_]] { def point[A](a: => A): F[A] } scalaz.Pure[F[_]] Был удалён в Scalaz 7
  40. 40. trait Applicative[F[_]] extends Apply[F] { def point[A](a: => A): F[A] } scalaz.Applicative[F[_]]
  41. 41. class List[A] { def flatMap[B](f: A => List[B]): List[B] } class Vector[A] { def flatMap[B](f: A => Vector[B]): Vector[B] } class Option[A] { def flatMap[B](f: A => Option[B]): Option[B] }
  42. 42. scalaz.Bind[F[_]] trait Bind[F[_]] extends Apply[F] { def bind[A,B](fa: F[A]) (f: A => F[B]): F[B] }
  43. 43. scala> some(some(5)).join res0: Option[Int] = Some(5) scala> List(List(1,2), List(3,4,5)).join res1: List[Int] = List(1,2,3,4,5)
  44. 44. scalaz.Monad[F[_]] trait Monad[F[_]] extends Applicative[F] with Bind[F] { … }
  • IlyaGalyetov

    Aug. 10, 2017
  • capkidd

    Jun. 24, 2016

Введение в Scalaz. Видео: http://www.youtube.com/watch?v=XXNdT83H89o

Vues

Nombre de vues

798

Sur Slideshare

0

À partir des intégrations

0

Nombre d'intégrations

60

Actions

Téléchargements

5

Partages

0

Commentaires

0

Mentions J'aime

2

×