Listen in Scala L. Piepmeyer: Funktionale Programmierung - Listen in Scala 1 Unveränderbare Listen scala.List ist der Typ für unveränderbare, verkettete Listen. Leere Listen definieren: val xs = List() val xs = Nil Bei einer leeren Liste ist der Elementetyp unwichtig! (Er ist der Bottom Type Nothing.) L. Piepmeyer: Funktionale Programmierung - Listen in Scala 2 Listen erzeugen Verwendung der Factory: val pizza = List("Yeast", "Water", "Flour") pizza: List[java.lang.String] = List(Yeast, Water, Flour) Was wurde da aufgerufen? Methode List.apply(xs: String*) L. Piepmeyer: Funktionale Programmierung - Listen in Scala 3 Listen erzeugen Alternativ mit dem cons-Operator: val pizza = "Yeast" :: "Water" :: "Flour" :: Nil Was ist am ::-Operator ungewöhnlich? L. Piepmeyer: Funktionale Programmierung - Listen in Scala 4 Einfache Operationen scala> pizza head res2: java.lang.String = Yeast scala> pizza tail res3: List[java.lang.String] = List(Water, Flour) scala> pizza length res4: Int = 3 L. Piepmeyer: Funktionale Programmierung - Listen in Scala 5 Listenmuster Für Listen gibt es intuitive Muster: def shopping(xs: List[String]): String = xs match { case v::Nil => v case v::ys => v + "\n"+ shopping(ys) } Extraktormuster def shopping(xs: List[String]): String = xs match { case List(v) => v case List(v, _*) => v + "\n"+ shopping(xs tail) } L. Piepmeyer: Funktionale Programmierung - Listen in Scala 6 Listen verknüpfen Listen können verkettet werden: toppings = List("Cheese", "Tomato") pizza:::toppings Wie beurteilen Sie die Komplexität des :::-Operators? L. Piepmeyer: Funktionale Programmierung - Listen in Scala 7 Direkter Zugriff Was passiert eigentlich beim Aufruf von pizza(2) L. Piepmeyer: Funktionale Programmierung - Listen in Scala 8 Ersatz für contains In der Klasse List gibt es die Methode contains. Es gibt zahlreiche Alternativen (didaktisch interessant): pizza exists (s => s=="Flour") pizza exists (_=="Flour") !( pizza forall(_!="Flour") ) pizza.count(_=="Flour") > 0 !pizza.filter(_=="Flour").isEmpty L. Piepmeyer: Funktionale Programmierung - Listen in Scala 9 Quicksort kompakt def sort(xs: List[String]): List[String] = xs match { case pivot::ys => sort(ys filter (pivot <=)) ::: List(pivot)::: sort(ys filter (pivot >)) case Nil => Nil } L. Piepmeyer: Funktionale Programmierung - Listen in Scala 10 Die Faltung Rechte Faltung: scala> pizza.foldRight("")((x,accu)=>(x+" "+accu)) res39: String = "Yeast Water Flour " Linke Faltung: scala> pizza.foldLeft("")((x,accu)=>(x+" "+accu)) res12: String = " Yeast Water Flour" L. Piepmeyer: Funktionale Programmierung - Listen in Scala 11 Faltung kurz Für die Faltung kennt Scala Abkürzungen ("" /: pizza) ((x,accu)=>x+" "+accu) (pizza :\ "") ((x,accu)=>x+" "+accu) L. Piepmeyer: Funktionale Programmierung - Listen in Scala 12 Alles klar? Generische, unveränderbare Listen sind der prominenteste Vertreter des Scala-CollectionFrameworks Die Klasse List bietet zusammen mit ihrem Begleiterobjekt sehr viel Funktionalität. Mit Hilfe des Listenextraktors kann PatternMatchings durchgeführt werden. Mit Methoden höherer Ordnung können komplexe Abfragen an Listen formuliert werden. L. Piepmeyer: Funktionale Programmierung - Listen in Scala 13