ШФП 17.04.2015.pptx
- Количество слайдов: 70
ИГОРЬ ПОСТАНОГОВ, ИРИНА ПЛЕШКОВА, АЛЕКСАНДР НИКОЛАЕВИЧ ПОЛЕЩУК ПЕРМЬ, 2015 1
Кратко о Scala (что) Объектно-функциональный язык программирования Разрабатывается с 2001 года Компилируется в байт-код Java, поддерживает Java-библиотеки 2
Кратко о Scala (кто) Разрабатывается в лаборатории методов программирования Федеральной политехнической школы Лозанны (Швейцария) под руководством Мартина Одерски Community - 100 к+ человек. 40 к+ репозиториев на Git. Hub 3
Кратко о Scala (преимущества) Объектно-ориентированность Функциональность JVM-совместимость Краткость и лаконичность Высокоуровневость Статическая типизированность 4
Компиляция …scala-2. 11. 6bin>scalac Hello. World. scala …scala-2. 11. 6bin>scala Hello. World Hello, world! 5
Менеджеры сборки проектов Независимость от OS. Управление зависимостями. Возможна сборка из командной строки. Хорошая интеграция со средами разработки. Декларативное описание проекта. 6
pom. xml (Maven) …
Сборка Scala-проекта (Maven) 1. 2. Исходные коды в папку «src/main/scala»
build. sbt (SBT) organization : = "com. mycompany. app" name : = "my-app" version : = "1. 0 -SNAPSHOT" scala. Version : = "2. 11. 6" library. Dependencies += "junit" % "4. 8. 2" % "test" 9
Сборка Scala-проекта (SBT) 1. Исходные коды в папку «src/main/scala» 2. > sbt package 10
IDE 4 Scala IDE for Eclipse Intelli. J IDEA ◦ + Community Edition ◦ Scala plugin ◦ SBT plugin (удобное окно терминала) Net. Beans ◦ Scala plugin 11
Hello, world! package perm. tryfuture object Hello. World { def main(args: Array[String]): Unit = { println("Hello, world!") } } 12
Коллекции 13
Типизированные коллекции object Parameterized. Arrays 1 extends App { val greet. Strings = new Array[String](3) greet. Strings(0) = "Hello" greet. Strings(1) = ", " greet. Strings(2) = "world!n" for (i <- 0 to 2) print(greet. Strings(i)) } 14
Типизированные коллекции (2) object Parameterized. Arrays 2 extends App { val greet. Strings = new Array[String](3) greet. Strings. update(0, "Hello") greet. Strings. update(1, ", ") greet. Strings. update(2, "world!n") for (i <- 0. to(2)) print(greet. Strings. apply(i)) } 15
Типизированные коллекции (3) object Parameterized. Arrays 3 extends App { val greet. Strings = Array[String]("Hello", ", ", "world!n") for (i <- 0. to(2)) print(greet. Strings. apply(i)) } 16
Типизированные коллекции (4) object Parameterized. Arrays 4 extends App { val greet. Strings = Array. apply[String]("Hello", ", ", "world!n") for (i <- 0. to(2)) print(greet. Strings. apply(i)) } 17
Типизированные коллекции (5) object Parameterized. Arrays 5 extends App { val greet. Strings 1 = List[String]("Hello", ", ", "world!n") val greet. Strings 2: List[String] = List("Hello", ", ", "world!n") val greet. Strings 3 = "Hello" : : ", " : : "world!n" : : List. empty for (i <- 0. to(2)) print(greet. Strings 3. apply(i)) } 18
Обход коллекций object Print. Args 1 { def main(args: Array[String]) { var i = 0 while (i < args. length) { println(args(i)) i += 1 } } } 19
Обход коллекций (2) object Print. Args 2 { def main(args: Array[String]) { args. foreach((arg: String) => println(arg)) } } 20
Обход коллекций (3) object Print. Args 3 { def main(args: Array[String]) { args. foreach(arg => println(arg)) } } 21
Обход коллекций (4) object Print. Args 4 { def main(args: Array[String]) { args. foreach(println) } } 22
Обход коллекций (5) object Print. Args 5 { def main(args: Array[String]) { for (arg <- args) println(arg) } } 23
Трансформация коллекций object High. Order 1 extends App { List(1, 2, 3) map (_ + 1) // List(2, 3, 4) val words = List("the", "quick", "brown") words map (_. length) // List(3, 5, 5) words map (_. to. List. reverse. mk. String) // List(eht, kciuq, nworb) } 24
Трансформация коллекций (2) object High. Order 2 extends App { val ints = List(1, 2, 3) map (_ + 1) // List(2, 3, 4) ints. reduce((a, b) => a + b) // 9 ints. filter(_ % 2 == 0) // List(2, 4) ints. exists(_ % 5 == 0) // false ints. forall(_. is. Instance. Of[Int]) // true } 25
Изменение коллекций object Collections. Mutation 1 extends App { var jet. Set = scala. collection. immutable. Set("Boeing", "Airbus") jet. Set += "Lear" println(jet. Set. contains("Cessna")) } 26
Изменение коллекций (2) object Collections. Mutation 2 extends App { val jet. Set = scala. collection. mutable. Set("Boeing", "Airbus") jet. Set += "Lear" println(jet. Set. contains("Cessna")) } 27
Операции над списками List() or Nil thrill. exists(s => s == "until") thrill. last List("Cool", "tools", "rule") thrill. filter(s => s. length == 4) thrill. length val thrill = "Will" : : "fill" : : "until" : : Nil thrill. forall(s => s. ends. With("l")) thrill. map(s => s + "y") List("a", "b") : : : List("c", "d") thrill. foreach(s => print(s)) thrill. mk. String(", ") thrill(2) thrill. foreach(print) thrill. remove(s => s. length == 4) thrill. count(s => s. length == 4) thrill. head thrill. reverse thrill. drop(2) thrill. init thrill. sort((s, t) => s. char. At(0). to. Lower. Case < t. char. At(0). to. Lower. Case) thrill. drop. Right(2) thrill. is. Empty thrill. tail 28
Сопоставление с образцом 29
Кортежи object Tuple. Example extends App { val pair = (99, "Luftballons") println(pair. _1) println(pair. _2) } 30
Сопоставление с образцом object Pattern. Matching 1 extends App { val pair = (99, "Luftballons") if (pair. _1 == 99) { println("99 with " + pair. _2) } else if (pair. _2 == "Magic") { println("Non 99 magic!") } else { println("Not a 99 nor magic : (") } } 31
Сопоставление с образцом (2) object Pattern. Matching 2 extends App { val pair = (99, "Luftballons") pair match { case (99, b) => println("99! with " + b) case (a, "Magic") => println("Non 99 magic!") case (a, b) => println("Not a 99 nor magic : (") } } 32
Сопоставление с образцом (3) object Pattern. Matching 3 extends App { val pair = (99, "Luftballons") pair match { case (99, b) => println(s"99! with $b") case (_, "Magic") => println("Non 99 magic!") case (_, _) => println("Not a 99 nor magic : (") } } 33
Сопоставление с образцом (4) object Pattern. Matching 4 extends App { val pair = (99, "Luftballons") pair match { case (99, b) => println(s"99! with $b") case (_, "Magic") => println("Non 99 magic!") case _ => println("Not a 99 nor magic : (") } } 34
Сопоставление с образцом (5) object Pattern. Matching 5 extends App { val pair = (99, "Luftballons") pair match { case (99, b) => println(s"99! with $b") case _: Double => // Error: pattern type is // incompatible with expected type; // found : Double, // required: (Int, String) println("Double!") } } 35
Сопоставление с образцом (6) object Pattern. Matching 6 extends App { val pair = (99, "Luftballons") pair match { case (a, b) if a == 99 => println(s"99! with $b") case (_, b) if b. starts. With("Magic") => println("Non 99 start magic!") case _ => println("Not a 99 nor start magic : (") } } 36
Сопоставление с образцом (7) object Pattern. Matching 7 extends App { val list = List(1, 2, 3, 4) list match { case Nil => println("Empty list") case a : : Nil => println("Single element") case a : : b : : Nil => println("Two elements") case _ => println("A lot of elements") } } 37
Сопоставление с образцом (8) object Pattern. Matching 8 extends App { val list = List(1, 2, 3, 4) println(list match { case Nil => "Empty list" case a : : Nil => "Single element" case a : : b : : Nil => "Two elements" case _ => "A lot of elements" }) } 38
Сопоставление с образцом (9) object Pattern. Matching 9 extends App { val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo") for ((country, city) <- capitals) println("The capital of " + country + " is " + city) } 39
Сопоставление с образцом (10) object Pattern. Matching 10 extends App { val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo") capitals. map { case (country, city) => println("The capital of " + country + " is " + city) } } 40
Сопоставление с образцом (10) object Pattern. Matching 11 extends App { val pair = (99, "Luftballons") val (number, str) = pair println(number + " " + str) } 41
Опциональное значение public class Option. Example 1 { public static void main(String[] args) { Hash. Map
Опциональное значение (2) object Option. Example 2 extends App { val vehicles = Map("BMW" -> 5, "Ford" -> 10) val result: Option[Int] = vehicles. get("Lada") result match { case Some(value) => println(value) case None => println("None") } } 43
Опциональное значение (3) object Option. Example 3 extends App { val vehicles = Map("BMW" ->(5, 25), "Ford" ->(10, 100)) val result: Option[(Int, Int)] = vehicles. get("Ford") result match { case Some((5, b)) => println(b) case Some(x) => println(x) case None => println("None") } } 44
Опциональное значение (4) object Option. Example 4 extends App { val results: List[Option[String]] = List(Some("apple"), None, Some("orange")) for (Some(fruit) <- results) println(fruit) // apple // orange } 45
Либо …, либо … object Either. Example extends App { val in = scala. io. Std. In. read. Line("Type Either a string or an Int: ") val result: Either[String, Int] = try { Right(in. to. Int) } catch { case e: Exception => Left(in) } println(result match { case Right(x) => "Int: " + x case Left(x) => "String: " + x }) } 46
Case-классы abstract class Expr case class Var(name: String) extends Expr case class Number(num: Double) extends Expr case class Un. Op(operator: String, arg: Expr) extends Expr case class Bin. Op(operator: String, left: Expr, right: Expr) extends Expr 47
Case-классы (2) object Case. Class. Example 1 extends App { def simplify. Top(expr: Expr): Expr = expr match { case Un. Op("-", e)) => e // Double negation case Bin. Op("+", e, Number(0)) => e // Adding zero case Bin. Op("*", e, Number(1)) => e // Multiplying by one case _ => expr } println(simplify. Top(Un. Op("-", Var("x"))))) // Var(x) } 48
Case-классы sealed abstract class Expr case class Var(name: String) extends Expr case class Number(num: Double) extends Expr case class Un. Op(operator: String, arg: Expr) extends Expr case class Bin. Op(operator: String, left: Expr, right: Expr) extends Expr 49
Case-классы (3) object Case. Class. Example 2 extends App { def describe(e: Expr): String = e match { case Number(_) => "a number" case Var(_) => "a variable" } // Warning: match may not be exhaustive. // It would fail on the following inputs: // Bin. Op(_, _, _), Un. Op(_, _) // def describe(e: Expr): String = e match { // ^ } 50
Примеси 51
Интерфейсы с реализацией trait Logger { protected def logger. Id: String protected def print(message: String) def info(message: String) { print(s"$logger. Id [info] $message") } def warning(message: String) { print(s"$logger. Id [warning] $message") } def error(message: String) { print(s"$logger. Id [error] $message") } } 52
Поля и методы trait Logger { protected def logger. Id: String } trait Static. Id. Logger extends Logger { protected val logger. Id = "My. Id" } 53
Ромбовидное наследование 54
Линеаризация наследования trait Drawable { def draw(): Unit } trait Cowboy extends Drawable { override def draw() { println("Bang!") } } trait Artist extends Drawable { override def draw() { println("A pretty painting") } } object Main extends App { (new Cowboy with Artist). draw() (new Artist with Cowboy). draw() } 55
Неявные преобразования sealed abstract class Money { def amount: Double } case class Dollar(amount: Double) extends Money case class Euro(amount: Double) extends Money object Implicits extends App { def pay(x: Dollar) = ? ? ? pay(Euro(2)) // Error: type mismatch; found : Euro; required: Dollar } 56
Неявные преобразования (2) sealed abstract class Money { def amount: Double } case class Dollar(amount: Double) extends Money case class Euro(amount: Double) extends Money object Implicits 2 extends App { implicit def euro. To. Dollar(euro: Euro) = { Dollar(euro. amount * 1. 04) } def pay(x: Dollar) = ? ? ? pay(Euro(2)) } 57
Неявные преобразования (3) object Implicits 3 extends App { implicit class Transliteration(non. Latin: String) { def to. Latin. LC = Transliterator. get. Instance("Any-Latin"). transform(non. Latin) } val latin = "Нечто". to. Latin. LC } 58
Операции над функциями 59
Каррирование object Fun 1 extends App { val sum = (x: Int, y: Int) => x + y val sum. B = (x: Int) => (y: Int) => x + y val plus. One = sum. B(1) plus. One(4) // 5 val sum. C: (Int) => Int = sum. curried } 60
Каррирование object Fun 2 extends App { def pay(user: String, amount: Int, reason: String): Unit = { println(s"$user $amount <$reason>") } val user = "You" val pay. Cur: (String) => (Int) => (String) => Unit = (pay _). curried val pay. UCur: (Int) => (String) => Unit = pay. Cur(user) val pay. U: (Int, String) => Unit = Function. uncurried(pay. UCur) val pay. UReasoned: (Int) => Unit = pay. U(_: Int, "Re@s 0 n") // val pay. UReasoned 2: (Int) => Unit = pay(user, _: Int, "Re@s 0 n") List(1, 2, 3). foreach(pay. UReasoned) } 61
Отложенные вычисления 62
Lazy-переменные object Laziness 1 extends App { val a = { println("a!"); 1 } lazy val b = { println("b!"); 1 } println("~") a+1 println("&") b+1 // a! // ~ // & // b! } 63
Lazy-параметры object Laziness 2 extends App { def dice. Print(consuming: => String) = { if (scala. util. Random. next. Boolean()) println(consuming) println("Done!") } dice. Print({Thread. sleep(1000); "Tough"}) } 64
Потоки object Laziness 3 extends App { val fibs: Stream[Big. Int] = Big. Int(0) #: : Big. Int(1) #: : fibs. zip(fibs. tail). map { n => n. _1 + n. _2 } fibs take 125 foreach println } 65
Ресурсы (курсы) Functional Programming Principles in Scala ◦ https: //ru. coursera. org/course/progfun Principles of Reactive Programming ◦ https: //ru. coursera. org/course/reactive Introduction to Functional Programming (Haskell) ◦ https: //www. edx. org/course/introduction-functional-programming-delftx-fp 101 x 66
Ресурсы (интерактивное обучение) Scala Exercises ◦ http: //scala-exercises. 47 deg. com/ Learn Scala with the Koans ◦ http: //www. scalakoans. org/ 67
Ресурсы (книги/статьи) Programming in Scala, First Edition ◦ http: //www. artima. com/pins 1 ed/ Scala By Example ◦ http: //www. scala-lang. org/docu/files/Scala. By. Example. pdf A Scala Tutorial for Java programmers ◦ http: //www. scala-lang. org/docu/files/Scala. Tutorial. pdf Путеводитель неофита по Scala ◦ https: //github. com/anton-k/ru-neophyte-guide-to-scala/ Прочее ◦ http: //bit. ly/scalinks 68
Источники http: //www. slideshare. net/Odersky/scala-the-simple-parts http: //www. scala-academy. com/blog/8 -considerations-on-choosing-a-programming-language https: //blog. safaribooksonline. com/2013/05/30/traits-how-scala-tames-multiple-inheritance/ http: //habrahabr. ru/post/251303/ 69
Контакты Школа функционального программирования (г. Пермь) ◦ https: //vk. com/tryfuture Игорь Постаногов ◦ ipostanogov@outlook. com ◦ https: //vk. com/ipostanogov Ирина Плешкова ◦ https: //vk. com/id 55765115 Александр Николаевич Полещук ◦ alex@ics. perm. ru 70