+ All Categories
Home > Documents > Schwarze Magie...ÜberblickDependent typesCollectionsKindsTypäquivalenzHeterogeneous Lists Über...

Schwarze Magie...ÜberblickDependent typesCollectionsKindsTypäquivalenzHeterogeneous Lists Über...

Date post: 26-Jan-2021
Category:
Upload: others
View: 3 times
Download: 0 times
Share this document with a friend
90
Schwarze Magie Scalas Typsystem ausgenutzt Lars Hupel
Transcript
  • Schwarze MagieScalas Typsystem ausgenutzt

    Lars Hupel

  • Schwarze MagieScalas Typsytem ausgenutztHerbstcampus 2011 – S32

    Lars [email protected]

    8. September 2011

    [email protected]

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Über den Autor

    I Informatik-Student, TU MünchenI Java-Programmierer seit 5 JahrenI Scala-Programmierer seit 2 JahrenI Interesse an formalen Methoden, Typsystemen, ...

    Lars Hupel Schwarze Magie 8. September 2011 2 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Werbung

    Scala EnthusiastenMetropolregion Nürnberg

    Lars Hupel Schwarze Magie 8. September 2011 3 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Scalas Typsystem

    I Grundlage bleibt objektorientiertI erweiterte TypinferenzI SingletonsI Existential typesI Definition-site varianceI Implizite Konversionen und ParameterI ...

    Lars Hupel Schwarze Magie 8. September 2011 4 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Innere KlassenJava vs. Scala

    Javaclass Outer {

    class Inner {}

    }

    Outer o = new Outer();Outer.Inner i = o.new Inner();

    Lars Hupel Schwarze Magie 8. September 2011 5 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Innere KlassenJava vs. Scala

    JavaI nicht-statische innere Klassen haben Referenz auf äußere

    KlasseI Instanziierung benötigt äußeres ObjektI aber: alle inneren Objekte haben selben Typ

    Lars Hupel Schwarze Magie 8. September 2011 6 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Innere KlassenJava vs. Scala

    JavaI nicht-statische innere Klassen haben Referenz auf äußere

    KlasseI Instanziierung benötigt äußeres ObjektI aber: alle inneren Objekte haben selben Typ

    Lars Hupel Schwarze Magie 8. September 2011 6 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Innere KlassenJava vs. Scala

    Scalaclass Outer {

    class Inner}

    val outer = new Outer()val i1: outer.Inner = new outer.Inner()val i2: Outer#Inner = i1

    Lars Hupel Schwarze Magie 8. September 2011 7 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Innere KlassenJava vs. Scala

    ScalaI Referenz auf äußeres Objekt wird Teil des TypsI innere Objekte zweier verschiedener äußerer Objekte nicht

    miteinander kompatibelI Probleme bei Java-InteroperabilitätI Lösung: Projektion Outer#Inner

    Lars Hupel Schwarze Magie 8. September 2011 8 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Bereichsdatentyp

    I eine Objekt ist mit einem Zahlenbereich assoziiertI Methoden dieses Objekts sollen nun nur auf Zahlen aus

    diesem Bereich operierenI Zahlen außerhalb des Bereichs sollen zu Compiler-Fehler

    führen

    Lars Hupel Schwarze Magie 8. September 2011 9 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Bereichsdatentyp

    I eine Objekt ist mit einem Zahlenbereich assoziiertI Methoden dieses Objekts sollen nun nur auf Zahlen aus

    diesem Bereich operierenI Zahlen außerhalb des Bereichs sollen zu Compiler-Fehler

    führen

    Lars Hupel Schwarze Magie 8. September 2011 9 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    BereichsdatentypImplementation

    class Range(begin: Int, end: Int) {class RangeInt private[Range](val n: Int) {

    def next: Option[Range.this.RangeInt] =if (n < end) Some(new RangeInt(n+1))else None

    }

    def first = new RangeInt(begin)def last = new RangeInt(end)

    }

    class HasRange {val myRange: Range = new Range(1, 10)def func(i: myRange.RangeInt) = println(i.n)

    }Lars Hupel Schwarze Magie 8. September 2011 10 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    BereichsdatentypVerwendung

    > new HasRange()res0: HasRange = HasRange@5b927504> res0.func(res0.myRange.first)1

    > new Range(11, 20)res1: Range = Range@790f2f3c> res0.func(res1.first)error: type mismatch;found : res1.RangeIntrequired: res0.myRange.RangeInt

    Lars Hupel Schwarze Magie 8. September 2011 11 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Singletons

    Scala ordnet einigen Werten einen eindeutigen Typen zu, der abernicht immer inferiert wird

    > class Foo> val foo = new Foo {}foo: Foo = Foo@608a6351

    > checkType(foo)Foo

    > checkType[foo.type](foo)[email protected]

    Lars Hupel Schwarze Magie 8. September 2011 12 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Singletons und Implicitsapply/update

    class Sugar {def apply(i: Int) = idef update(i: Int, value: Int) = ()

    }

    val sugar = new Sugar()

    sugar(3) sugar.apply(3)sugar(3) = 5 sugar.update(3, 5)

    Lars Hupel Schwarze Magie 8. September 2011 13 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Singletons und ImplicitsSymbol

    ’a Symbol.apply("a")’a = 0 Symbol.update("a", 0)

    aber: Symbol hat keine update-Methode

    Lars Hupel Schwarze Magie 8. September 2011 14 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Singletons und ImplicitsSymbol

    ’a Symbol.apply("a")’a = 0 Symbol.update("a", 0)

    aber: Symbol hat keine update-Methode

    Lars Hupel Schwarze Magie 8. September 2011 14 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Singletons und ImplicitsSymbol

    implicit def pimpSymbol(s: Symbol.type) = new {def update(str: String, newVal: Any) =

    println(str + " := " + newVal)}

    > ’a = "foo"a := foo

    Lars Hupel Schwarze Magie 8. September 2011 15 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Collections in 2.8

    Scalas Collections wurden mit 2.8 komplett überarbeitet:Transformationen liefern immer den bestmöglichen Typ

    möglich durch CanBuildFrom

    Lars Hupel Schwarze Magie 8. September 2011 16 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Collections in 2.8

    Scalas Collections wurden mit 2.8 komplett überarbeitet:Transformationen liefern immer den bestmöglichen Typ

    möglich durch CanBuildFrom

    Lars Hupel Schwarze Magie 8. September 2011 16 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    CanBuildFrom

    trait CanBuildFrom[-From, -Elem, +To] {

    def apply(from: From): Builder[Elem, To]

    def apply(): Builder[Elem, To]

    }

    Lars Hupel Schwarze Magie 8. September 2011 17 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    CanBuildFrom

    CanBuildFrom ermöglicht es, über Collections zu abstrahieren

    CanBuildFrom[From, Elem, To] bedeutet: es ist möglich...I auf Grundlage einer Collection des Typs FromI mit Elementen des Zieltyps ElemI eine Collection des Typs To

    ... zu erstellen

    Lars Hupel Schwarze Magie 8. September 2011 18 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    CanBuildFrom

    CanBuildFrom ermöglicht es, über Collections zu abstrahieren

    CanBuildFrom[From, Elem, To] bedeutet: es ist möglich...I auf Grundlage einer Collection des Typs FromI mit Elementen des Zieltyps ElemI eine Collection des Typs To

    ... zu erstellen

    Lars Hupel Schwarze Magie 8. September 2011 18 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    CanBuildFrom

    CanBuildFrom ermöglicht es, über Collections zu abstrahieren

    CanBuildFrom[From, Elem, To] bedeutet: es ist möglich...I auf Grundlage einer Collection des Typs FromI mit Elementen des Zieltyps ElemI eine Collection des Typs To

    ... zu erstellen

    Lars Hupel Schwarze Magie 8. September 2011 18 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    CanBuildFrom

    CanBuildFrom ermöglicht es, über Collections zu abstrahieren

    CanBuildFrom[From, Elem, To] bedeutet: es ist möglich...I auf Grundlage einer Collection des Typs FromI mit Elementen des Zieltyps ElemI eine Collection des Typs To

    ... zu erstellen

    Lars Hupel Schwarze Magie 8. September 2011 18 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    QuicksortSchritt 1: Signatur definieren

    Traversable

    Iterable

    Seq Set Map

    IndexedSeq LinearSeq SortedSet BitSet SortedMap

    http://www.decodified.com/scala/collections-api.xml, Mathias, CC-by 3.0

    Lars Hupel Schwarze Magie 8. September 2011 19 / 61

    http://www.decodified.com/scala/collections-api.xml

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    QuicksortSchritt 1: Signatur definieren

    def sort[T, Coll](a: Coll)(implicit ev: Coll

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    QuicksortSchritt 1: Signatur definieren

    def sort[T, Coll](a: Coll)(implicit ev: Coll

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    QuicksortSchritt 1: Signatur definieren

    def sort[T, Coll](a: Coll)(implicit ev: Coll

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    QuicksortSchritt 1: Signatur definieren

    def sort[T, Coll](a: Coll)(implicit ev: Coll

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    QuicksortSchritt 1: Signatur definieren

    def sort[T, Coll](a: Coll)(implicit ev: Coll

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    QuicksortSchritt 2: Implementation

    Demo

    Lars Hupel Schwarze Magie 8. September 2011 23 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Werte und TypenTerminologie

    I Datenkonstruktoren erzeugen DatenI in Java: „Konstruktoren“I Typkonstruktoren erzeugen TypenI in Java: „generische Klasse“I auch bekannt als „parametrische Polymorphie“

    Lars Hupel Schwarze Magie 8. September 2011 24 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Werte und TypenTerminologie

    I Datenkonstruktoren erzeugen DatenI in Java: „Konstruktoren“I Typkonstruktoren erzeugen TypenI in Java: „generische Klasse“I auch bekannt als „parametrische Polymorphie“

    Lars Hupel Schwarze Magie 8. September 2011 24 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Werte und TypenTerminologie

    I Datenkonstruktoren erzeugen DatenI in Java: „Konstruktoren“I Typkonstruktoren erzeugen TypenI in Java: „generische Klasse“I auch bekannt als „parametrische Polymorphie“

    Lars Hupel Schwarze Magie 8. September 2011 24 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Werte und TypenTerminologie

    I Datenkonstruktoren erzeugen DatenI in Java: „Konstruktoren“I Typkonstruktoren erzeugen TypenI in Java: „generische Klasse“I auch bekannt als „parametrische Polymorphie“

    Lars Hupel Schwarze Magie 8. September 2011 24 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Werte und TypenKinds

    „Kind“ bezeichnet die Struktur eines Typkonstruktors

    NotationI * steht für beliebigen TypI -> steht für Abbildung

    Lars Hupel Schwarze Magie 8. September 2011 25 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Werte und TypenKinds

    „Kind“ bezeichnet die Struktur eines Typkonstruktors

    NotationI * steht für beliebigen TypI -> steht für Abbildung

    Lars Hupel Schwarze Magie 8. September 2011 25 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Werte und TypenKinds

    „Kind“ bezeichnet die Struktur eines Typkonstruktors

    NotationI * steht für beliebigen TypI -> steht für Abbildung

    Lars Hupel Schwarze Magie 8. September 2011 25 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Typen und KindsBeispiele

    Typ Deklaration KindListe class List[A] * -> *Paar class Tuple2[A, B] (* x *) -> *Applikation type Ap[T[_], S] = T[S] ((* -> *) x *) -> *

    Lars Hupel Schwarze Magie 8. September 2011 26 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Methoden und Funktionen

    I Methoden sind keine first class citizenI Funktionen sind „gewöhnliche“ Objekte mit apply-MethodeI Methode −→ Funktion per f _

    aber: Was ist mit generischen Methoden?

    Lars Hupel Schwarze Magie 8. September 2011 27 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Methoden und Funktionen

    I Methoden sind keine first class citizenI Funktionen sind „gewöhnliche“ Objekte mit apply-MethodeI Methode −→ Funktion per f _

    aber: Was ist mit generischen Methoden?

    Lars Hupel Schwarze Magie 8. September 2011 27 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Methoden und FunktionenNotwendigkeit von Kinds

    def transform[A](opt: Option[A]): List[A] =opt.toList

    > transform _res0: Option[Nothing] => List[Nothing] =

    Lars Hupel Schwarze Magie 8. September 2011 28 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Methoden und FunktionenNotwendigkeit von Kinds

    trait ~>[-A[_], +B[_]] {def apply[T](a: A[T]): B[T]

    }

    new (Option ~> List) {def apply[T](opt: Option[T]): List[T] =

    opt.toList}

    Erkenntnis: Kinds erhöhen die Ähnlichkeit von Methoden undFunktionen

    Lars Hupel Schwarze Magie 8. September 2011 29 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Methoden und FunktionenNotwendigkeit von Kinds

    trait ~>[-A[_], +B[_]] {def apply[T](a: A[T]): B[T]

    }

    new (Option ~> List) {def apply[T](opt: Option[T]): List[T] =

    opt.toList}

    Erkenntnis: Kinds erhöhen die Ähnlichkeit von Methoden undFunktionen

    Lars Hupel Schwarze Magie 8. September 2011 29 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Kindinferenz

    I ... ist so gut wie nicht vorhandenI explizite Deklaration erforderlichI Inferenz der Parameter beim Aufruf einer solchen Methode

    schlägt oft fehl

    Lars Hupel Schwarze Magie 8. September 2011 30 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Typäquivalenz

    Problemgenerische Klasse, bei der einige Methoden nur bei speziellenTypparametern angeboten werden

    Lösung: impliziter „Beweis“

    Lars Hupel Schwarze Magie 8. September 2011 31 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Typäquivalenz

    Problemgenerische Klasse, bei der einige Methoden nur bei speziellenTypparametern angeboten werden

    Lösung: impliziter „Beweis“

    Lars Hupel Schwarze Magie 8. September 2011 31 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Naive Implementation

    class =:=[From, To] extends (From => To)

    implicit def tpEquals[A] = new =:=[A, A]

    DisclaimerI Zugriffsschutz fehltI Casten kann nicht verhindert werden

    Lars Hupel Schwarze Magie 8. September 2011 32 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Naive ImplementationVerwendung

    trait Generic[A] {

    val a: A

    def onlyForString(implicit ev: A =:= String) =a.charAt(0)

    }

    Lars Hupel Schwarze Magie 8. September 2011 33 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Naive Implementation

    NachteileI aus A =:= B kann nicht B =:= A konstruiert werdenI aus A =:= B und B =:= C kann nicht A =:= C konstruiert

    werdenI aus A =:= B kann nicht F[A] =:= F[B] konstruiert werdenI keine vollständige Äquivalenz auf Typebene

    Lars Hupel Schwarze Magie 8. September 2011 34 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Naive Implementation

    NachteileI aus A =:= B kann nicht B =:= A konstruiert werdenI aus A =:= B und B =:= C kann nicht A =:= C konstruiert

    werdenI aus A =:= B kann nicht F[A] =:= F[B] konstruiert werdenI keine vollständige Äquivalenz auf Typebene

    Lars Hupel Schwarze Magie 8. September 2011 34 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Naive Implementation

    NachteileI aus A =:= B kann nicht B =:= A konstruiert werdenI aus A =:= B und B =:= C kann nicht A =:= C konstruiert

    werdenI aus A =:= B kann nicht F[A] =:= F[B] konstruiert werdenI keine vollständige Äquivalenz auf Typebene

    Lars Hupel Schwarze Magie 8. September 2011 34 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Naive Implementation

    NachteileI aus A =:= B kann nicht B =:= A konstruiert werdenI aus A =:= B und B =:= C kann nicht A =:= C konstruiert

    werdenI aus A =:= B kann nicht F[A] =:= F[B] konstruiert werdenI keine vollständige Äquivalenz auf Typebene

    Lars Hupel Schwarze Magie 8. September 2011 34 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Naive Implementation

    NachteileI aus A =:= B kann nicht B =:= A konstruiert werdenI aus A =:= B und B =:= C kann nicht A =:= C konstruiert

    werdenI aus A =:= B kann nicht F[A] =:= F[B] konstruiert werdenI keine vollständige Äquivalenz auf Typebene

    Lars Hupel Schwarze Magie 8. September 2011 34 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit Kinds

    trait Leibniz[A,B] {def subst[F[_]](p: F[A]) : F[B]

    }

    abgekürzt als A ~ B

    Lars Hupel Schwarze Magie 8. September 2011 35 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit Kinds

    F[A] A~B F[B]

    Lars Hupel Schwarze Magie 8. September 2011 36 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit KindsKonvertierungsfunktion

    Wie bekommt man aus A ~ B ein A => B?

    F[A]A=>A B=>A

    A~B F[B]

    Lars Hupel Schwarze Magie 8. September 2011 37 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit KindsKonvertierungsfunktion

    Wie bekommt man aus A ~ B ein A => B?

    F[A]A=>A B=>A

    A~B F[B]

    Lars Hupel Schwarze Magie 8. September 2011 37 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit KindsKonvertierungsfunktion

    def witness[A,B](f: A ~ B): A => B =f.subst(identity[A] _)

    argument expression’s type is not compatiblewith formal parameter type;found : A => Arequired: ?F[A]

    Lars Hupel Schwarze Magie 8. September 2011 38 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit KindsKonvertierungsfunktion

    def witness[A,B](f: A ~ B): A => B =f.subst(identity[A] _)

    argument expression’s type is not compatiblewith formal parameter type;found : A => Arequired: ?F[A]

    Lars Hupel Schwarze Magie 8. September 2011 38 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit KindsKonvertierungsfunktion

    def witness[A,B](f: A ~ B): A => B =f.subst[({type L[X]=A => X})#L](identity)

    Lars Hupel Schwarze Magie 8. September 2011 39 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit KindsInversion

    F[A]A~A B~A

    A~B F[B]

    def symm[A,B](f: A ~ B) : B ~ A =f.subst[({type L[X]=X ~ A})#L](refl)

    Lars Hupel Schwarze Magie 8. September 2011 40 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation mit KindsLifting

    F[A]T[A]~T[A]

    A~B F[B]T[A]~T[B]

    def lift[T[_], A, B](a: A ~ B): (T[A] ~ T[B]) = {type L[X] = T[A] ~ T[X]a.subst[L](refl)

    }

    Lars Hupel Schwarze Magie 8. September 2011 41 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Heterogeneous Lists

    ProblemFunktionen mit mehreren Rückgabewerten

    Standardlösung: Verwendung von Tupeln

    Lars Hupel Schwarze Magie 8. September 2011 42 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Heterogeneous Lists

    Nachteile von TupelnI in Scala: jede Stelligkeit eigene KlasseI begrenzte Stelligkeit

    Lösung: Heterogeneous Lists(statisch typisierte) Listen mit uneinheitlichen Elementtypen

    Lars Hupel Schwarze Magie 8. September 2011 43 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Heterogeneous Lists

    Nachteile von TupelnI in Scala: jede Stelligkeit eigene KlasseI begrenzte Stelligkeit

    Lösung: Heterogeneous Lists(statisch typisierte) Listen mit uneinheitlichen Elementtypen

    Lars Hupel Schwarze Magie 8. September 2011 43 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Heterogeneous Lists

    Nachteile von TupelnI in Scala: jede Stelligkeit eigene KlasseI begrenzte Stelligkeit

    Lösung: Heterogeneous Lists(statisch typisierte) Listen mit uneinheitlichen Elementtypen

    Lars Hupel Schwarze Magie 8. September 2011 43 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Implementation

    sealed trait HList

    final case class HCons[H, T

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Verwendung

    Erzeugung

    > def getValues = 3 :: "foo" :: HNilgetValues: HCons[Int,HCons[String,HNil.type]]

    > getValuesres0: HCons[...] = HCons(3,HCons(foo,HNil))

    Lars Hupel Schwarze Magie 8. September 2011 45 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Verwendung

    Pattern Matching

    > getValues match { case HCons(x, _) => x }res0: Int = 3

    > getValues match {case HCons(_, HCons(y, _)) => y

    }res1: String = foo

    Lars Hupel Schwarze Magie 8. September 2011 46 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    VerwendungIndexbasierter Zugriff

    I eine Funktion HList[H, T] => Int => Any möglich, abernicht hilfreich

    I Idee: index-Funktion muss einen Typparameter haben, derdie Position in der Liste repräsentiert

    Lösung: Peano-Numerale

    Lars Hupel Schwarze Magie 8. September 2011 47 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    VerwendungIndexbasierter Zugriff

    I eine Funktion HList[H, T] => Int => Any möglich, abernicht hilfreich

    I Idee: index-Funktion muss einen Typparameter haben, derdie Position in der Liste repräsentiert

    Lösung: Peano-Numerale

    Lars Hupel Schwarze Magie 8. September 2011 47 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Peano-Numerale

    Wertbasierttrait Natcase object Zerocase class Succ(n: Nat)

    val two = Succ(Succ(Zero))

    Lars Hupel Schwarze Magie 8. September 2011 48 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Peano-Numerale

    Typbasiert

    trait Nattrait Zero extends Nattrait Succ[N

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Peano-Numerale und HListsZugriffstrait

    trait AccessN[L

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Peano-Numerale und HListsHCons revisited

    case class HCons[H, T

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Peano-Numerale und HListsImplementation

    implicit def accessZero[H, T

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Peano-Numerale und HLists

    3 foo 5.3 Nil

    Zero

    HCons[String, HCons[Double,HNil.type]HCons[Int,

    Succ[ ]

    ]]

    Lars Hupel Schwarze Magie 8. September 2011 53 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Peano-Numerale und HListsVerwendung

    val _0 = new Zero {}val _1 = new Succ[Zero] {}val _2 = ...

    Lars Hupel Schwarze Magie 8. September 2011 54 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Peano-Numerale und HListsVerwendung

    > val list = 3 :: "foo" :: 5.3 :: HNil

    > list(_0)res0: Int = 3

    > list(_1)res1: String = foo

    > list(_3)error: could not find implicit value for parameter ...

    Lars Hupel Schwarze Magie 8. September 2011 55 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Heterogeneous Lists

    VorteileI Verwalten von verschiedenen Typen, ohne eine Klasse anlegen

    zu müssenI Tupel beliebiger StelligkeitI kein Verlust von Typinformationen verglichen mit List[Any]I Compiler kann falsche Verwendung erkennenI dank Scalas Syntaxzucker „fühlen“ sich HLists wie normale

    Listen anI sind auch in Java möglich, aber viel Overhead nötig

    Lars Hupel Schwarze Magie 8. September 2011 56 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Anwendung

    Problem: Signatur von String.format stellt nicht sicher, dass dieArgumente zum Formatstring passen Compiler kann Fehler nicht aufspüren

    Idee: Funktion konstruieren, die eine HList von den Argumentennimmt und diese formatiert

    Lars Hupel Schwarze Magie 8. September 2011 57 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Anwendung

    Problem: Signatur von String.format stellt nicht sicher, dass dieArgumente zum Formatstring passen Compiler kann Fehler nicht aufspüren

    Idee: Funktion konstruieren, die eine HList von den Argumentennimmt und diese formatiert

    Lars Hupel Schwarze Magie 8. September 2011 57 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Typsicheres printfImplementation

    Demo

    Lars Hupel Schwarze Magie 8. September 2011 58 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Typsicheres printf

    VorteileI Compiler kann Formatierung prüfenI weniger ExceptionsI selbst definierte Operatoren erhöhen (richtig eingesetzt) die

    Lesbarkeit

    Lars Hupel Schwarze Magie 8. September 2011 59 / 61

  • Überblick Dependent types Collections Kinds Typäquivalenz Heterogeneous Lists

    Typsicheres printf

    NachteileI gezeigte Lösung vereinfacht, benötigt noch Tricks zum LaufenI Fehlermeldungen können sehr unübersichtlich werdenI „Denken in Typen“ erfordert in der Regel einige Eingewöhnung

    Lars Hupel Schwarze Magie 8. September 2011 60 / 61

  • Fragen?

    http://www.lars-hupel.dehttp://gplus.to/larsrh

    http://www.lars-hupel.dehttp://gplus.to/larsrh

Recommended