Przygotował: Jacek Sroka. PO* - Scala (iteratory, leniwość, view bounds i konwersje)

Podobne dokumenty
Scala + NetBeans AKA: Nowoczesne obiektowe języki programowania i środowiska programistyczne na przykładzie Scali i środowiska NetBeans

Scala + NetBeans AKA: Nowoczesne obiektowe języki programowania i środowiska programistyczne na przykładzie Scali i środowiska NetBeans

Przygotował: Jacek Sroka. PO* - Scala (typy uogólnione, listy)

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

PO* - Scala (typy uogólnione, listy)

Scala. Wprowadzenie do języka.

Programowanie obiektowe

Kurs programowania. Wykład 9. Wojciech Macyna

Podstawy otwartych języków programowania Przechowywanie danych

Przygotował: Jacek Sroka. JNP 3 język Scala

Platformy Programistyczne Podstawy języka Java

Wzorce logiki dziedziny

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Dawid Gierszewski Adam Hanasko

Programowanie Komputerów

Wątki. Definiowanie wątków jako klas potomnych Thread. Nadpisanie metody run().

Scala. Obiektowo-funkcyjny język programowania. Zbyszek Skowron

Podstawy Programowania C++

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Scala - programowanie obiektowo-funkcyjne

Klasy abstrakcyjne, interfejsy i polimorfizm

Lista, Stos, Kolejka, Tablica Asocjacyjna

DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0

Systemy Rozproszone. Spis treści. Temat projektu: Regułowy system analizujacy logi. autorzy: Rafał Sadłowski, Sebastian Falkus, Michał Różycki

Programowanie obiektowe

Microsoft IT Academy kurs programowania

Programowanie obiektowe

Wstęp do Programowania potok funkcyjny

Java: interfejsy i klasy wewnętrzne

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Db4o obiektowa baza danych wersja.net

Podstawy programowania III WYKŁAD 6

Bloki anonimowe w PL/SQL

WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy

Zaawansowany kurs języka Python

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Języki formalne i techniki translacji

Programowanie i projektowanie obiektowe

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Wstęp do programowania

Wstęp do programowania. Różne różności

Laboratorium z przedmiotu: Inżynieria Oprogramowania INEK Instrukcja 7

0.1 Hierarchia klas Diagram Krótkie wyjaśnienie

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Algorytmy i Struktury Danych.

Diagramy maszyn stanowych, wzorce projektowe Wykład 5 część 1

Realizacja ekstensji klasy. Paulina Strzelecka, Tomasz Roszkowski

LibreOffice Calc VBA

Programowanie obiektowe

Python. Wprowadzenie. Jolanta Bachan

Języki skryptowe w programie Plans

java.util.* :Kolekcje Tomasz Borzyszkowski

Paradygmaty programowania. Paradygmaty programowania

Języki programowania wysokiego poziomu. PHP cz.2.

Bloki anonimowe w PL/SQL

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Języki Programowania II Wykład 3. Java podstawy. Przypomnienie

Kolekcje w Javie cz. 1

Informatyka 1. Przetwarzanie tekstów

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

import java.util.*; public class ListExample { public static void main(string args[]) { List<String> lista1= new ArrayList<String> ();

INSTRUKCJA PUSTA. Nie składa się z żadnych znaków i symboli, niczego nie robi. for i := 1 to 10 do {tu nic nie ma};

Programowanie Obiektowe (Java)

Programowanie w języku C++

I - Microsoft Visual Studio C++

Język JAVA podstawy. Wykład 4, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Programowanie - instrukcje sterujące

Wprowadzenie do języka Ruby

Języki programowania Haskell

Języki i metody programowania Java INF302W Wykład 2 (część 1)

Programowanie obiektowe i zdarzeniowe

Wstęp do ruby dla programistów javy

Programowanie obiektowe

Klasy i obiekty cz II

Bazy danych dla producenta mebli tapicerowanych. Bartosz Janiak Marcin Sikora Wrocław r.

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Wydział Zarządzania AGH. Katedra Informatyki Stosowanej. Pętle. Programowanie komputerowe

Dynamiczne struktury danych

w PL/SQL bloki nazwane to: funkcje, procedury, pakiety, wyzwalacze

Kurs języka Python Wykład 8. Przetwarzanie tekstu Wyrażenia regularne Biblioteka urllib Parsowanie html'a XML

Programowanie Obiektowe Ćwiczenie 4

Wykład 7: Pakiety i Interfejsy

Polimorfizm a klasy generyczne w języku Java. Zdzisław Spławski 1

akademia androida Składowanie danych część VI

Przygotował: Jacek Sroka. Scala Wprowadzenie

Wprowadzenie db4o - podstawy db4o - technikalia Przydatne wiadomości. Wprowadzenie. db4o. Norbert Potocki. 1 czerwca Norbert Potocki db4o

Budowa aplikacji wielowarstwowych zastosowanie szablonów. Laboratorium 2 Programowanie komponentowe Zofia Kruczkiewicz

Przykład -

Programowanie obiektowe

Tworzenie stron internetowych z wykorzystaniem HTM5, JavaScript, CSS3 i jquery. Łukasz Bartczuk

Pętle. for, while, do... while, foreach. Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.

Kompilacja javac prog.java powoduje wyprodukowanie kilku plików o rozszerzeniu.class, m.in. Main.class wykonanie: java Main

Podstawy programowania w Pythonie

Język C++ część 9 szablony klas. Jarosław Gramacki Instytut Informatyki i Elektroniki. szablony funkcji

Wykład 3 Funkcje wyższych rzędów

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Obiektowy Caml. Paweł Boguszewski

dziedziczenie - po nazwie klasy wystąpią słowa: extends nazwa_superklasy

Transkrypt:

1 PO* - Scala (iteratory, leniwość, view bounds i konwersje)

2 Iteratory Iteratory to imperatywne wersje strumieni Po danych poruszamy się metodami hasnext() i next() (może nie być struktury danych) trait Iterator[+A] { def hasnext: Boolean def next: A... Przykład val it: Iterator[Int] = Iterator.range(1, 100) while (it.hasnext) { val x = it.next println(x * x)

3 Przydatne metody iteratorów Iteratory posiadają wiele metod wzorowanych na listach append def append[b >: A](that: Iterator[B]): Iterator[B] = new Iterator[B] { def hasnext = Iterator.this.hasNext that.hasnext def next = if (Iterator.this.hasNext) Iterator.this.next else that.next Czemu służy składnia Iterator.this.hasNext? map def map[b](f: A => B): Iterator[B] = new Iterator[B] { def hasnext = Iterator.this.hasNext def next = f(iterator.this.next)

4 Przydatne metody iteratorów c.d. flatmap def flatmap[b](f: A => Iterator[B]): Iterator[B] = new Iterator[B] { private var cur: Iterator[B] = Iterator.empty def hasnext: Boolean = if (cur.hasnext) true else if (Iterator.this.hasNext) {cur = f(iterator.this.next); hasnext else false def next: B = if (cur.hasnext) cur.next else if (Iterator.this.hasNext) { cur = f(iterator.this.next); next else error("next on empty iterator") foreach def foreach(f: A => Unit): Unit = while (hasnext) { f(next)

5 Przydatne metody iteratorów c.d. filter def filter(p: A => Boolean) = new BufferedIterator[a] { private val source = Iterator.this.buffered private def skip { while (source.hasnext &&!p(source.head)) { source.next def hasnext: Boolean = { skip; source.hasnext def next: A = { skip; source.next def head: A = { skip; source.head gdzie: trait BufferedIterator[+A] extends Iterator[A] { def head: A Skoro jest map, flatmap, filter i foreach to są też for-comprehensions i for-loops for (i <- Iterator.range(1, 100)) println(i * i)

6 Przydatne metody iteratorów c.d. zip def zip[b](that: Iterator[B]) = new Iterator[(a, b)] { def hasnext = Iterator.this.hasNext && that.hasnext def next = {Iterator.this.next, that.next

7 Konstruowanie iteratorów Najprostszy iterator to Iterator.empty object empty extends Iterator[Nothing] { def hasnext = false def next = error("next on empty iterator") Iterator na tablicy def fromarray[a](xs: Array[A]) = new Iterator[A] { private var i = 0 def hasnext: Boolean = i < xs.length def next: A = if (i < xs.length) { val x = xs(i); i += 1; x else error("next on empty iterator")

8 Konstruowanie iteratorów c.d. Iterator na przedziale Iterator.range def range(start: Int, end: Int) = new Iterator[Int] { private var current = start def hasnext = current < end def next = { val r = current if (current < end) current += 1 else error("end of iterator") r Nieskończony ciąg licz całkowitych (w praktyce iterujący w kółko po reprezentacji int) def from(start: Int) = new Iterator[Int] { private var last = start - 1 def hasnext = true def next = { last += 1; last

9 Przykład zastosowań Wypisywanie tablicy xs: Array[Int] Iterator.fromArray(xs) foreach (x => println(x)) for (x <- Iterator.fromArray(xs)) println(x) Znajdywanie indeksów elementów tablicy o wartości większej niż zadana stała import Iterator._ fromarray(xs).zip(from(0)).filter((x, i) => x > limit).map((x, i) => i)?

10 Przykład zastosowań Wypisywanie tablicy xs: Array[Int] Iterator.fromArray(xs) foreach (x => println(x)) for (x <- Iterator.fromArray(xs)) println(x) Znajdywanie indeksów elementów tablicy o wartości większej niż zadana stała import Iterator._ fromarray(xs).zip(from(0)).filter((x, i) => x > limit).map((x, i) => i) import Iterator._ for ((x, i) <- fromarray(xs) zip from(0); if x > limit) yield i

11 Wbudowana leniwość Przykład: obsługa bazy pracowników, gdzie każdy pracownik ma szefa i zespół Z gorliwą inicjalizacją większość danych jest od razu wczytywana do pamięci case class Employee(id: Int, name: String, managerid: Int) { val manager: Employee = Db.get(managerId) val team: List[Employee] = Db.team(id) Z leniwą inicjalizacją nie case class Employee(id: Int, name: String, managerid: Int) { lazy val manager: Employee = Db.get(managerId) lazy val team: List[Employee] = Db.team(id)

12 Przykład c.d. Poniższa implementacja bazy informuje kiedy wczytywane są dane. object Db { val table = Map(1 -> (1, "Haruki Murakami", 1), 2 -> (2, "Milan Kundera", 1), 3 -> (3, "Jeffrey Eugenides", 1), 4 -> (4, "Mario Vargas Llosa", 1), 5 -> (5, "Julian Barnes", 2)) def team(id: Int) = { for (rec <table.values.tolist; if rec._3 == id) yield rectoemployee(rec) def get(id: Int) = rectoemployee(table(id)) private def rectoemployee(rec: (Int, String, Int)) = { println("[db] fetching " + rec._1) Employee(rec._1, rec._2, rec._3)

13 Leniwość a cykliczne zależności Bez leniwości rekursja przy inicjalizacji wartości lokalnych jest niedozwolona class Symbols(val compiler: Compiler) { import compiler.types._ val Add = new Symbol("+", FunType(List(IntType, IntType), IntType)) val Sub = new Symbol("-", FunType(List(IntType, IntType), IntType)) class Symbol(name: String, tpe: Type) { override def tostring = name + ": " + tpe class Types(val compiler: Compiler) { import compiler.symtab._ abstract class Type case class FunType(args: List[Type], res: Type) extends Type case class NamedType(sym: Symbol) extends Type case object IntType extends Type

14 Leniwość a cykliczne zależności c.d. Tu będzie błąd w chwili wykonania class Compiler { val symtab = new Symbols(this) val types = new Types(this) A tu nie (zostanie wybrana właściwa kolejność) class Compiler { lazy val symtab = new Symbols(this) lazy val types = new Types(this)

15 Implicit parameters Półgrupa abstract class SemiGroup[A] { def add(x: A, y: A): A Monoid abstract class Monoid[A] extends SemiGroup[A] { def unit: A Implementacje object stringmonoid extends Monoid[String] { def add(x: String, y: String): String = x.concat(y) def unit: String = "" object intmonoid extends Monoid[Int] { def add(x: Int, y: Int): Int = x + y def unit: Int = 0

16 Implicit parameters Funkcja sumująca listy wartości z dowolnego monoidu def sum[a](xs: List[A])(m: Monoid[A]): A = if (xs.isempty) m.unit else m.add(xs.head, sum(xs.tail)(m)) sum(list("a", "bc", "def"))(stringmonoid) sum(list(1, 2, 3))(intMonoid) Co zrobić żeby drugi parametr był odgadywany tak samo jak zazwyczaj kompilator odgaduje typ?

17 Implicite parameters Ostatnia lista parametrów może być wyróżniona słowem implicit def sum[a](xs: List[A])(implicit m: Monoid[A]): A = if (xs.isempty) m.unit else m.add(xs.head, sum(xs.tail)) Takim samym słowem trzeba też wyróżnić obiekty oraz deklaracje implicit object stringmonoid extends Monoid[String] { def add(x: String, y: String): String = x.concat(y) def unit: String = "" implicit object intmonoid extends Monoid[Int] { def add(x: Int, y: Int): Int = x + y def unit: Int = 0 Scala wybierze najbardziej pasującą wartość z miejsca wywołania metody

18 Konwersje Jeżeli wyrażenie zwraca wartość innego typu niż spodziewany Scala spróbuje skorzystać z dostępnych konwersji implicit def int2ordered(x: Int): Ordered[Int] = new Ordered[Int] { def compare(y: Int): Int = if (x < y) -1 else if (x > y) 1 else 0

19 View Bounds Można parametryzować typami, dla których istnieją wymagane konwersje def sort[a <% Ordered[A]](xs: List[A]): List[A] = if (xs.isempty xs.tail.isempty) xs else { val {ys, zs = xs.splitat(xs.length / 2) merge(ys, zs) To lukier dla (żądamy konwersji) def sort[a](xs: List[A])(implicit c: A => Ordered[A]): List[A] =...

20 View Bounds c.d. Kontynuująć def merge[a <% Ordered[A]](xs: List[A], ys: List[A]): List[A] = if (xs.isempty) ys else if (ys.isempty) xs else if (xs.head < ys.head) xs.head :: merge(xs.tail, ys) else if ys.head :: merge(xs, ys.tail) To lukier dla def merge[a](xs: List[A], ys: List[A])(implicit c: A => Ordered[A]): List[A] = if (xs.isempty) ys else if (ys.isempty) xs else if (c(xs.head) < ys.head) xs.head :: merge(xs.tail, ys) else if ys.head :: merge(xs, ys.tail)(c)