diff -r f70d74fea67f -r 2a30c7dfe3ed progs/lecture5.scala --- a/progs/lecture5.scala Sun Sep 15 12:57:59 2024 +0100 +++ b/progs/lecture5.scala Mon Jul 21 16:38:07 2025 +0100 @@ -1,110 +1,12 @@ // Scala Lecture 5 //================= -for (n <- (1 to 10).toList) yield { - val add = 10 - n + add -} - -println(add) - -List(1,2,3,4).sum - -// extension methods -// implicit conversions -// (Immutable) OOP - -// Cool Stuff in Scala -//===================== - - -// Extensions or How to Pimp your Library -//====================================== - -// For example adding your own methods to Strings: -// Imagine you want to increment strings, like -// -// "HAL".increment -// -// you can avoid ugly fudges, like a MyString, by -// using extensions. - -extension (s: String) { - def increment = s.map(c => (c + 1).toChar) -} - -"HAL".increment - - - -// a more relevant example - -import scala.concurrent.duration.{TimeUnit,SECONDS,MINUTES} - -case class Duration(time: Long, unit: TimeUnit) { - def +(o: Duration) = - Duration(time + unit.convert(o.time, o.unit), unit) -} - -extension (that: Int) { - def seconds = Duration(that, SECONDS) - def minutes = Duration(that, MINUTES) -} +def foo(n: Int) = ??? -2.minutes + 60.seconds -5.seconds + 2.minutes //Duration(125, SECONDS ) - - -// Implicit Conversions -//===================== - - - -// Regular expressions - the power of DSLs in Scala -//================================================== - -abstract class Rexp -case object ZERO extends Rexp // nothing -case object ONE extends Rexp // the empty string -case class CHAR(c: Char) extends Rexp // a character c -case class ALT(r1: Rexp, r2: Rexp) extends Rexp // alternative r1 + r2 -case class SEQ(r1: Rexp, r2: Rexp) extends Rexp // sequence r1 . r2 -case class STAR(r: Rexp) extends Rexp // star r* - -val r = STAR(CHAR('a')) - - -// some convenience for typing in regular expressions -import scala.language.implicitConversions -import scala.language.reflectiveCalls +fop(10) -def charlist2rexp(s: List[Char]): Rexp = s match { - case Nil => ONE - case c::Nil => CHAR(c) - case c::s => SEQ(CHAR(c), charlist2rexp(s)) -} - -given Conversion[String, Rexp] = (s => charlist2rexp(s.toList)) - -extension (r: Rexp) { - def | (s: Rexp) = ALT(r, s) - def % = STAR(r) - def ~ (s: Rexp) = SEQ(r, s) -} - -val r1 = CHAR('a') | CHAR('b') | CHAR('c') -val r2 = CHAR('a') ~ CHAR('b') - -val r3 : Rexp = "hello world" - - -//example regular expressions -val digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" -val sign = "+" | "-" | "" -val number = sign ~ digit ~ digit.% - - - +List.fill(1)(100) +// (Immutable) OOP // Object Oriented Programming in Scala // ===================================== @@ -164,50 +66,6 @@ } -// In mandelbrot.scala I used complex (imaginary) numbers -// and implemented the usual arithmetic operations for complex -// numbers. - -case class Complex(re: Double, im: Double) { - // represents the complex number re + im * i - def +(that: Complex) = Complex(this.re + that.re, this.im + that.im) - def -(that: Complex) = Complex(this.re - that.re, this.im - that.im) - def *(that: Complex) = Complex(this.re * that.re - this.im * that.im, - this.re * that.im + that.re * this.im) - def *(that: Double) = Complex(this.re * that, this.im * that) - def abs = Math.sqrt(this.re * this.re + this.im * this.im) -} - -// usual way to reference methods -//object.method(....) - -val test = Complex(1, 2) + (Complex (3, 4)) - - -import scala.language.postfixOps -(List(5,4,3,2,1) sorted) reverse - -// this could have equally been written as -val test = Complex(1, 2).+(Complex (3, 4)) - -// this applies to all methods, but requires -import scala.language.postfixOps - -List(5, 2, 3, 4).sorted -List(5, 2, 3, 4) sorted - - -// ...to allow the notation n + m * i -import scala.language.implicitConversions - -val i = Complex(0, 1) - -given Conversion[Double, Complex] = (re => Complex(re, 0)) - -val inum1 = -2.0 + -1.5 * i -val inum2 = 1.0 + 1.5 * i - - // All is public by default....so no public is needed. // You can have the usual restrictions about private @@ -489,7 +347,7 @@ // up to a level def enuml(l: Int, s: String) : Set[Rexp] = l match { - case 0 => Set(ZERO, ONE) ++ s.map(CHAR).toSet + case 0 => Set(ZERO, ONE) ++ s.map(CHAR(_)).toSet case n => val rs = enuml(n - 1, s) rs ++