├── .gitignore ├── README.md ├── build.sbt ├── lecture slides ├── week 1 │ ├── 01 - Intro.pdf │ ├── 02 - Elements of Programming.pdf │ ├── 03 - Evaluation Strategies and Termination.pdf │ ├── 04 - Conditionals and Value Definitions.pdf │ ├── 05 - Sqrt Example.pdf │ ├── 06 - Blocks and Lexical Scope.pdf │ └── 07 - Tail Recursion.pdf ├── week 2 │ ├── 01 - High-Order Functions.pdf │ ├── 02 - Currying.pdf │ ├── 03 - Finding Fixed Points.pdf │ ├── 04 - Scala Syntax Summary.pdf │ ├── 05 - Functions and Data.pdf │ ├── 06 - More Fun with Rationals.pdf │ └── 07 - Evaluation and Operators.pdf ├── week 3 │ ├── 01 - Class Hierarchies.pdf │ ├── 02 - How Classes are Organized.pdf │ └── 03 - Polymorhism.pdf ├── week 4 │ ├── 01 - Objects Everywhere.pdf │ ├── 02 - Functions as Objects.pdf │ ├── 03 - Subtyping and Generics.pdf │ ├── 04 - Variance.pdf │ ├── 05 - Decomposition.pdf │ ├── 06 - Pattern Matching.pdf │ └── 07 - Lists.pdf ├── week 5 │ ├── 01 - More Functions on Lists.pdf │ ├── 02 - Pairs and Tuples.pdf │ ├── 03 - Implicit Parameters.pdf │ ├── 04 - Higher-order List Functions.pdf │ ├── 05 - Reduction of Lists.pdf │ ├── 06 - Reasoning About Lists.pdf │ └── 07 - A Larger Equational Proof on Lists.pdf └── week 6 │ ├── 01 - Other Collections.pdf │ ├── 02 - Combinatorial Search and For-Expressions.pdf │ ├── 03 - Combinatorial Search Example.pdf │ ├── 04 - Maps.pdf │ └── 05 - Putting the Pieces Together.pdf ├── project ├── build.properties └── plugins.sbt └── src └── main └── scala ├── week1 └── session.sc ├── week2 ├── Rational.scala ├── functions.sc └── rationals.sc ├── week3 ├── IntSet.scala ├── intsets.sc ├── overrides.sc └── scratch.sc ├── week4 ├── Expr.scala ├── List.scala ├── Nat.scala ├── exprs.sc └── nth.sc ├── week5 ├── 5-1-more-functions-on-lists.sc ├── 5-2-pairs-and-tuples.sc ├── 5-3-implicit-parameters.sc ├── 5-4-higher-order-list-functions.sc ├── 5-4-listfun.sc └── 5-5-reduction-of-lists.sc └── week6 ├── maps.sc ├── mnemonics.sc ├── nqueens.sc ├── pairs.sc ├── polynomials.sc └── test.sc /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | # sbt specific 5 | .cache 6 | .history 7 | .lib/ 8 | dist/* 9 | target/ 10 | lib_managed/ 11 | src_managed/ 12 | project/boot/ 13 | project/plugins/project/ 14 | 15 | # Scala-IDE specific 16 | .scala_dependencies 17 | .worksheet 18 | .cache-main 19 | .classpath 20 | .project 21 | .settings 22 | /bin/ 23 | 24 | # Intellij specific 25 | .idea 26 | 27 | # Mac OS specific 28 | .DS_Store 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # progfun1-code 2 | 3 | Crowd source for code used in the lectures of **Functional Programming Principles in Scala**. 4 | 5 | Pull requests are welcome! 6 | 7 | ## Contributors 8 | 9 | - Week 1: [@leanton](https://github.com/leanton) 10 | - Week 2: [@leanton](https://github.com/leanton) 11 | - Week 3: [@leanton](https://github.com/leanton) 12 | - Week 4: [@leanton](https://github.com/leanton) 13 | - Week 5: [@lbragaglia](https://github.com/lbragaglia) 14 | - Week 6: [@leanton](https://github.com/leanton) 15 | 16 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | name := "progfun1-code" 2 | 3 | version := "1.0" 4 | 5 | scalaVersion := "2.11.8" 6 | -------------------------------------------------------------------------------- /lecture slides/week 1/01 - Intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 1/01 - Intro.pdf -------------------------------------------------------------------------------- /lecture slides/week 1/02 - Elements of Programming.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 1/02 - Elements of Programming.pdf -------------------------------------------------------------------------------- /lecture slides/week 1/03 - Evaluation Strategies and Termination.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 1/03 - Evaluation Strategies and Termination.pdf -------------------------------------------------------------------------------- /lecture slides/week 1/04 - Conditionals and Value Definitions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 1/04 - Conditionals and Value Definitions.pdf -------------------------------------------------------------------------------- /lecture slides/week 1/05 - Sqrt Example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 1/05 - Sqrt Example.pdf -------------------------------------------------------------------------------- /lecture slides/week 1/06 - Blocks and Lexical Scope.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 1/06 - Blocks and Lexical Scope.pdf -------------------------------------------------------------------------------- /lecture slides/week 1/07 - Tail Recursion.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 1/07 - Tail Recursion.pdf -------------------------------------------------------------------------------- /lecture slides/week 2/01 - High-Order Functions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 2/01 - High-Order Functions.pdf -------------------------------------------------------------------------------- /lecture slides/week 2/02 - Currying.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 2/02 - Currying.pdf -------------------------------------------------------------------------------- /lecture slides/week 2/03 - Finding Fixed Points.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 2/03 - Finding Fixed Points.pdf -------------------------------------------------------------------------------- /lecture slides/week 2/04 - Scala Syntax Summary.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 2/04 - Scala Syntax Summary.pdf -------------------------------------------------------------------------------- /lecture slides/week 2/05 - Functions and Data.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 2/05 - Functions and Data.pdf -------------------------------------------------------------------------------- /lecture slides/week 2/06 - More Fun with Rationals.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 2/06 - More Fun with Rationals.pdf -------------------------------------------------------------------------------- /lecture slides/week 2/07 - Evaluation and Operators.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 2/07 - Evaluation and Operators.pdf -------------------------------------------------------------------------------- /lecture slides/week 3/01 - Class Hierarchies.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 3/01 - Class Hierarchies.pdf -------------------------------------------------------------------------------- /lecture slides/week 3/02 - How Classes are Organized.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 3/02 - How Classes are Organized.pdf -------------------------------------------------------------------------------- /lecture slides/week 3/03 - Polymorhism.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 3/03 - Polymorhism.pdf -------------------------------------------------------------------------------- /lecture slides/week 4/01 - Objects Everywhere.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 4/01 - Objects Everywhere.pdf -------------------------------------------------------------------------------- /lecture slides/week 4/02 - Functions as Objects.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 4/02 - Functions as Objects.pdf -------------------------------------------------------------------------------- /lecture slides/week 4/03 - Subtyping and Generics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 4/03 - Subtyping and Generics.pdf -------------------------------------------------------------------------------- /lecture slides/week 4/04 - Variance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 4/04 - Variance.pdf -------------------------------------------------------------------------------- /lecture slides/week 4/05 - Decomposition.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 4/05 - Decomposition.pdf -------------------------------------------------------------------------------- /lecture slides/week 4/06 - Pattern Matching.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 4/06 - Pattern Matching.pdf -------------------------------------------------------------------------------- /lecture slides/week 4/07 - Lists.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 4/07 - Lists.pdf -------------------------------------------------------------------------------- /lecture slides/week 5/01 - More Functions on Lists.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 5/01 - More Functions on Lists.pdf -------------------------------------------------------------------------------- /lecture slides/week 5/02 - Pairs and Tuples.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 5/02 - Pairs and Tuples.pdf -------------------------------------------------------------------------------- /lecture slides/week 5/03 - Implicit Parameters.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 5/03 - Implicit Parameters.pdf -------------------------------------------------------------------------------- /lecture slides/week 5/04 - Higher-order List Functions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 5/04 - Higher-order List Functions.pdf -------------------------------------------------------------------------------- /lecture slides/week 5/05 - Reduction of Lists.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 5/05 - Reduction of Lists.pdf -------------------------------------------------------------------------------- /lecture slides/week 5/06 - Reasoning About Lists.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 5/06 - Reasoning About Lists.pdf -------------------------------------------------------------------------------- /lecture slides/week 5/07 - A Larger Equational Proof on Lists.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 5/07 - A Larger Equational Proof on Lists.pdf -------------------------------------------------------------------------------- /lecture slides/week 6/01 - Other Collections.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 6/01 - Other Collections.pdf -------------------------------------------------------------------------------- /lecture slides/week 6/02 - Combinatorial Search and For-Expressions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 6/02 - Combinatorial Search and For-Expressions.pdf -------------------------------------------------------------------------------- /lecture slides/week 6/03 - Combinatorial Search Example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 6/03 - Combinatorial Search Example.pdf -------------------------------------------------------------------------------- /lecture slides/week 6/04 - Maps.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 6/04 - Maps.pdf -------------------------------------------------------------------------------- /lecture slides/week 6/05 - Putting the Pieces Together.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liufengyun/progfun1-code/5af897dde09ae7e119ba71c246ffc9a7fc132346/lecture slides/week 6/05 - Putting the Pieces Together.pdf -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version = 0.13.8 -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | logLevel := Level.Warn 2 | addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0") 3 | -------------------------------------------------------------------------------- /src/main/scala/week1/session.sc: -------------------------------------------------------------------------------- 1 | import scala.annotation.tailrec 2 | 3 | object session { 4 | 5 | def not(x: Boolean): Boolean = if (x) false else true 6 | 7 | def and(x: Boolean, y: => Boolean): Boolean = if (x) y else false 8 | 9 | def or(x: Boolean, y: => Boolean): Boolean = if (x) true else y 10 | 11 | not(true) 12 | not(false) 13 | 14 | and(true, true) 15 | and(true, false) 16 | and(false, true) 17 | and(false, false) 18 | 19 | or(true, true) 20 | or(true, false) 21 | or(false, true) 22 | or(false, false) 23 | 24 | def loop: Boolean = loop 25 | 26 | // these functions calls will terminate 27 | // because the second parameter is called by name 28 | and(false, loop) 29 | or(true, loop) 30 | 31 | def abs(x: Double): Double = if (x < 0) -x else x 32 | 33 | def sqrt(x: Double): Double = { 34 | def sqrtIter(guess: Double): Double = 35 | if (isGoodEnough(guess)) guess 36 | else sqrtIter(improve(guess)) 37 | 38 | def isGoodEnough(guess: Double): Boolean = 39 | abs(guess * guess - x) / x < 0.001 40 | 41 | def improve(guess: Double): Double = 42 | (guess + x / guess) / 2 43 | 44 | sqrtIter(1.0) 45 | } 46 | 47 | sqrt(2) 48 | 49 | @tailrec 50 | def gcd(a: Int, b: Int): Int = 51 | if (b == 0) a else gcd(b, a % b) 52 | 53 | gcd(14, 21) 54 | 55 | def factorial(n: Int): Int = { 56 | @tailrec 57 | def loop(n: Int, acc: Int): Int = 58 | if (n == 0) acc 59 | else loop(n - 1, n * acc) 60 | loop(n, 1) 61 | } 62 | 63 | factorial(5) 64 | 65 | } -------------------------------------------------------------------------------- /src/main/scala/week2/Rational.scala: -------------------------------------------------------------------------------- 1 | package week2 2 | 3 | class Rational(x: Int, y: Int) { 4 | require(y != 0, "denominator must be nonzero") 5 | 6 | /** 7 | * Another constructor, overloading the default 8 | **/ 9 | def this(x: Int) = this(x, 1) 10 | 11 | private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b) 12 | 13 | val numer = x / gcd(x, y) 14 | val denom = y / gcd(x, y) 15 | 16 | def <(that: Rational) = this.numer * that.denom < that.numer * this.denom 17 | 18 | def max(that: Rational) = if (this < that) that else this 19 | 20 | def +(that: Rational) = 21 | new Rational( 22 | this.numer * that.denom + that.numer * this.denom, 23 | this.denom * that.denom) 24 | 25 | def unary_- = new Rational(-this.numer, this.denom) 26 | 27 | def -(that: Rational) = this + -that 28 | 29 | def *(that: Rational) = 30 | new Rational(this.numer * that.numer, this.denom * that.denom) 31 | 32 | def /(that: Rational) = this * new Rational(that.denom, that.numer) 33 | 34 | override def toString = this.numer + "/" + this.denom 35 | } -------------------------------------------------------------------------------- /src/main/scala/week2/functions.sc: -------------------------------------------------------------------------------- 1 | import java.lang.Math._ 2 | 3 | import scala.annotation.tailrec 4 | 5 | object functions { 6 | 7 | // High-Order functions 8 | def sum(f: Int => Int)(a: Int, b: Int): Int = { 9 | @tailrec 10 | def loop(a: Int, acc: Int): Int = { 11 | if (a > b) acc 12 | else loop(a + 1, f(a) + acc) 13 | } 14 | loop(a, 0) 15 | } 16 | 17 | sum(x => x)(1, 10) 18 | 19 | // Using anonymous functions in argument 20 | def sumInts: (Int, Int) => Int = sum(x => x) 21 | 22 | def sumCubes: (Int, Int) => Int = sum(x => x * x * x) 23 | 24 | sumInts(1, 10) 25 | sumCubes(1, 10) 26 | 27 | def product(f: Int => Int)(a: Int, b: Int): Int = { 28 | @tailrec 29 | def loop(a: Int, acc: Int): Int = { 30 | if (a > b) acc 31 | else loop(a + 1, f(a) * acc) 32 | } 33 | loop(a, 1) 34 | } 35 | 36 | def productInts: (Int, Int) => Int = product(x => x) 37 | 38 | def productCubes: (Int, Int) => Int = product(x => x * x * x) 39 | 40 | productInts(1, 10) 41 | productCubes(1, 10) 42 | 43 | def factorial(n: Int): Int = product(x => x)(1, n) 44 | 45 | factorial(5) 46 | 47 | def mapReduce(f: Int => Int, combine: (Int, Int) => Int, zero: Int)(a: Int, b: Int): Int = { 48 | @tailrec 49 | def loop(a: Int, acc: Int): Int = { 50 | if (a > b) acc 51 | else loop(a + 1, combine(f(a), acc)) 52 | } 53 | loop(a, zero) 54 | } 55 | 56 | def su: (Int, Int) => Int = mapReduce(x => x, (x, y) => x + y, 0) 57 | 58 | su(1, 5) 59 | 60 | def prod: (Int, Int) => Int = mapReduce(x => x, (x, y) => x * y, 1) 61 | 62 | prod(1, 5) 63 | 64 | def fact(n: Int): Int = prod(1, n) 65 | 66 | fact(5) 67 | 68 | // EXAMPLE -- Finding fixed point 69 | val tolerance = 0.0001 70 | 71 | def isCloseEnough(x: Double, y: Double): Boolean = abs((x - y) / x) / x < tolerance 72 | 73 | def fixedPoint(f: Double => Double)(firstGuess: Double) = { 74 | def iterate(guess: Double): Double = { 75 | val next = f(guess) 76 | if (isCloseEnough(guess, next)) next 77 | else iterate(next) 78 | } 79 | iterate(firstGuess) 80 | } 81 | 82 | fixedPoint(x => 1 + x / 2)(1.0) 83 | 84 | def averageDamp(f: Double => Double)(x: Double) = (x + f(x)) / 2 85 | 86 | def sqrt(x: Double) = fixedPoint(averageDamp(y => x / y))(1.0) 87 | 88 | sqrt(4) 89 | sqrt(2) 90 | 91 | } -------------------------------------------------------------------------------- /src/main/scala/week2/rationals.sc: -------------------------------------------------------------------------------- 1 | import week2.Rational 2 | 3 | object rationals { 4 | 5 | val x = new Rational(1, 3) 6 | val y = new Rational(5, 7) 7 | val z = new Rational(3, 2) 8 | x.numer 9 | x.denom 10 | x - y - z 11 | y + y 12 | x < y 13 | x max y 14 | x * y 15 | x / y 16 | -x 17 | new Rational(2) 18 | 19 | } -------------------------------------------------------------------------------- /src/main/scala/week3/IntSet.scala: -------------------------------------------------------------------------------- 1 | package week3 2 | 3 | abstract class IntSet { 4 | def incl(x: Int): IntSet 5 | 6 | def contains(x: Int): Boolean 7 | 8 | def union(other: IntSet): IntSet 9 | } 10 | 11 | class Empty extends IntSet { 12 | def contains(x: Int): Boolean = false 13 | 14 | def incl(x: Int): IntSet = new NonEmpty(x, new Empty, new Empty) 15 | 16 | def union(other: IntSet): IntSet = other 17 | 18 | override def toString = "." 19 | } 20 | 21 | class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet { 22 | def contains(x: Int): Boolean = 23 | if (x < elem) left contains x 24 | else if (x > elem) right contains x 25 | else true 26 | 27 | def incl(x: Int): IntSet = 28 | if (x < elem) new NonEmpty(elem, left incl x, right) 29 | else if (x > elem) new NonEmpty(elem, left, right incl x) 30 | else this 31 | 32 | def union(other: IntSet): IntSet = 33 | left union (right union (other incl elem)) 34 | 35 | override def toString = "{" + left + elem + right + "}" 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/week3/intsets.sc: -------------------------------------------------------------------------------- 1 | import week3.{Empty, NonEmpty} 2 | 3 | object intsets { 4 | val t1 = new NonEmpty(3, new Empty, new Empty) 5 | val t2 = t1 incl 4 6 | val t3 = new NonEmpty(1, new Empty, new Empty) 7 | t3 union t2 8 | } -------------------------------------------------------------------------------- /src/main/scala/week3/overrides.sc: -------------------------------------------------------------------------------- 1 | object overrides { 2 | println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet 3 | } 4 | 5 | abstract class Base { 6 | def foo = 1 7 | 8 | def bar: Int 9 | } 10 | 11 | class Sub extends Base { 12 | override def foo = 2 13 | 14 | def bar = 3 15 | } -------------------------------------------------------------------------------- /src/main/scala/week3/scratch.sc: -------------------------------------------------------------------------------- 1 | import week2.Rational 2 | 3 | object scratch { 4 | new Rational(1, 2) 5 | 6 | 7 | def error(msg: String) = throw new Error(msg) 8 | 9 | val x = null 10 | val y: String = x 11 | 12 | if (true) 1 else false 13 | } -------------------------------------------------------------------------------- /src/main/scala/week4/Expr.scala: -------------------------------------------------------------------------------- 1 | package week4 2 | 3 | trait Expr { 4 | def eval: Int = this match { 5 | case Number(n) => n 6 | case Sum(e1, e2) => e1.eval + e2.eval 7 | case Prod(e1, e2) => e1.eval * e2.eval 8 | } 9 | 10 | def show: String = { 11 | def parens(e: Expr) = e match { 12 | case Sum(_, _) => "(" + e.show + ")" 13 | case _ => e.show 14 | } 15 | this match { 16 | case Number(n) => n.toString 17 | case Sum(l, r) => l.show + " + " + r.show 18 | case Prod(l, r) => parens(l) + " * " + parens(r) 19 | case Var(x) => x 20 | } 21 | } 22 | } 23 | 24 | case class Number(n: Int) extends Expr 25 | 26 | case class Sum(e1: Expr, e2: Expr) extends Expr 27 | 28 | case class Prod(e1: Expr, e2: Expr) extends Expr 29 | 30 | case class Var(x: String) extends Expr 31 | 32 | -------------------------------------------------------------------------------- /src/main/scala/week4/List.scala: -------------------------------------------------------------------------------- 1 | package week4 2 | 3 | import week3.{Empty, NonEmpty} 4 | 5 | trait List[+T] { 6 | def isEmpty: Boolean 7 | 8 | def head: T 9 | 10 | def tail: List[T] 11 | 12 | def prepend[U >: T](elem: U): List[U] = new Cons(elem, this) 13 | } 14 | 15 | class Cons[T](val head: T, val tail: List[T]) extends List[T] { 16 | def isEmpty: Boolean = false 17 | 18 | override def toString = "(" + head + tail + ")" 19 | } 20 | 21 | object Nil extends List[Nothing] { 22 | def isEmpty: Boolean = true 23 | 24 | def head: Nothing = throw new NoSuchElementException("Nil.head") 25 | 26 | def tail: Nothing = throw new NoSuchElementException("Nil.tail") 27 | 28 | override def toString = "." 29 | } 30 | 31 | object List { 32 | // List(1, 2) = List.apply(1, 2) 33 | def apply[T](x1: T, x2: T): List[T] = new Cons(x1, new Cons(x2, Nil)) 34 | 35 | def apply[T](x1: T): List[T] = new Cons(x1, Nil) 36 | 37 | def apply[T] = Nil 38 | } 39 | 40 | object test { 41 | def f(xs: List[NonEmpty], x: Empty) = xs prepend x 42 | } -------------------------------------------------------------------------------- /src/main/scala/week4/Nat.scala: -------------------------------------------------------------------------------- 1 | package week4 2 | 3 | // Peano numbers 4 | abstract class Nat { 5 | def isZero: Boolean 6 | 7 | def predecessor: Nat 8 | 9 | def successor: Nat = new Succ(this) 10 | 11 | def +(that: Nat): Nat 12 | 13 | def -(that: Nat): Nat 14 | } 15 | 16 | object Zero extends Nat { 17 | def isZero = true 18 | 19 | def predecessor = throw new Error("Zero.predecessor") 20 | 21 | def +(that: Nat) = that 22 | 23 | def -(that: Nat) = if (that.isZero) this else throw new Error("negative number") 24 | 25 | override def toString = "0" 26 | } 27 | 28 | class Succ(n: Nat) extends Nat { 29 | def isZero = false 30 | 31 | def predecessor = n 32 | 33 | def +(that: Nat) = new Succ(n + that) 34 | 35 | def -(that: Nat) = if (that.isZero) this else n - that.predecessor 36 | 37 | override def toString = "1+" + n 38 | } 39 | -------------------------------------------------------------------------------- /src/main/scala/week4/exprs.sc: -------------------------------------------------------------------------------- 1 | import week4._ 2 | 3 | object exprs { 4 | Sum(Number(5), Number(9)).show 5 | Sum(Prod(Number(2), Var("x")), Var("y")).show 6 | Prod(Sum(Number(2), Var("x")), Var("y")).show 7 | 8 | true match { 9 | case true => 10 | val x = 3 11 | val y = 5 12 | x * y 13 | case false => 10 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/week4/nth.sc: -------------------------------------------------------------------------------- 1 | import week4._ 2 | 3 | object nth { 4 | def nth[T](n: Int, xs: List[T]): T = 5 | if (xs.isEmpty) throw new IndexOutOfBoundsException 6 | else if (n == 0) xs.head 7 | else nth(n - 1, xs.tail) 8 | 9 | val list = new Cons(1, new Cons(2, new Cons(3, Nil))) 10 | nth(2, list) 11 | 12 | val list1 = List.apply(1, 2) 13 | val list2 = List(1, 2) 14 | 15 | val nil = Zero 16 | val one = nil.successor 17 | val two = one + one 18 | val thr = two + one 19 | val fou = two + two 20 | val fiv = two + thr 21 | val dif = fiv - thr 22 | 23 | // val x = Number(5).eval //> x : Int = 5 24 | } -------------------------------------------------------------------------------- /src/main/scala/week5/5-1-more-functions-on-lists.sc: -------------------------------------------------------------------------------- 1 | object lecture1 { 2 | 3 | // Implementation of 'last' (slides 3-7) 4 | def last[T](xs: List[T]): T = xs match { 5 | case List() => throw new Error("last of empty list") 6 | case List(x) => x 7 | case y :: ys => last(ys) 8 | } 9 | 10 | // Exercise: Implementation of 'init' (slides 8-9) 11 | def init[T](xs: List[T]): List[T] = xs match { 12 | case List() => throw new Error("init of empty list") 13 | case List(x) => List() 14 | case y :: ys => y :: init(ys) 15 | } 16 | 17 | // Implementation of 'concat' (slides 10-14) 18 | def concat[T](xs: List[T], ys: List[T]): List[T] = xs match { 19 | case List() => ys 20 | case z :: zs => z :: concat(zs, ys) 21 | } 22 | 23 | // Implementation of 'reverse' (slides 15-17) 24 | def reverse[T](xs: List[T]): List[T] = xs match { 25 | case List() => xs 26 | case y :: ys => reverse(ys) ++ List(y) 27 | } 28 | 29 | // 30 | // Exercises 31 | // 32 | 33 | val fruit = List("apples", "oranges", "pears") 34 | val nums = List(1, 2, 3) 35 | val diag3 = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) 36 | val empty = List() 37 | 38 | // Exercise 39 | def removeAt[T](n: Int, xs: List[T]) = (xs take n) ::: (xs drop n + 1) 40 | 41 | removeAt(1, nums) 42 | removeAt(1, List("a", "b", "c", "d")) 43 | 44 | // Exercise (harder, optional) 45 | def flatten(xs: List[Any]): List[Any] = ??? 46 | 47 | flatten(diag3) 48 | flatten(List(List(1, 1), 2, List(3, List(5, 8)))) 49 | 50 | } -------------------------------------------------------------------------------- /src/main/scala/week5/5-2-pairs-and-tuples.sc: -------------------------------------------------------------------------------- 1 | object mergesort { 2 | 3 | def msort(xs: List[Int]): List[Int] = { 4 | val n = xs.length / 2 5 | if (n == 0) xs 6 | else { 7 | /* 8 | // Initial version without pair patterns 9 | def merge(xs: List[Int], ys: List[Int]): List[Int] = xs match { 10 | case Nil => ys 11 | case x :: xs1 => ys match { 12 | case Nil => xs 13 | case y :: ys1 => 14 | if (x < y) x :: merge(xs1, ys) 15 | else y :: merge(xs, ys1) 16 | } 17 | } 18 | */ 19 | def merge(xs: List[Int], ys: List[Int]): List[Int] = (xs, ys) match { 20 | case (Nil, ys) => ys 21 | case (xs, Nil) => xs 22 | case (x :: xs1, y :: ys1) => 23 | if (x < y) x :: merge(xs1, ys) 24 | else y :: merge(xs, ys1) 25 | } 26 | val (fst, snd) = xs splitAt n 27 | merge(msort(fst), msort(snd)) 28 | } 29 | } 30 | 31 | val nums = List(2, -4, 5, 7, 1) 32 | msort(nums) 33 | 34 | } -------------------------------------------------------------------------------- /src/main/scala/week5/5-3-implicit-parameters.sc: -------------------------------------------------------------------------------- 1 | import math.Ordering 2 | 3 | object mergesort2 { 4 | 5 | /* 6 | def msort[T](xs: List[T])(lt: (T, T) => Boolean): List[T] = { 7 | val n = xs.length / 2 8 | if (n == 0) xs 9 | else { 10 | def merge(xs: List[T], ys: List[T]): List[T] = (xs, ys) match { 11 | case (Nil, ys) => ys 12 | case (xs, Nil) => xs 13 | case (x :: xs1, y :: ys1) => 14 | if (lt(x, y)) x :: merge(xs1, ys) 15 | else y :: merge(xs, ys1) 16 | } 17 | val (fst, snd) = xs splitAt n 18 | merge(msort(fst)(lt), msort(snd)(lt)) 19 | } 20 | } 21 | */ 22 | 23 | //def msort[T](xs: List[T])(ord: Ordering[T]): List[T] = { 24 | def msort[T](xs: List[T])(implicit ord: Ordering[T]): List[T] = { 25 | val n = xs.length / 2 26 | if (n == 0) xs 27 | else { 28 | def merge(xs: List[T], ys: List[T]): List[T] = (xs, ys) match { 29 | case (Nil, ys) => ys 30 | case (xs, Nil) => xs 31 | case (x :: xs1, y :: ys1) => 32 | if (ord.lt(x, y)) x :: merge(xs1, ys) 33 | else y :: merge(xs, ys1) 34 | } 35 | val (fst, snd) = xs splitAt n 36 | //merge(msort(fst)(ord), msort(snd)(ord) 37 | merge(msort(fst), msort(snd)) 38 | } 39 | } 40 | 41 | val nums = List(-5, 6, 3, 2, 7) 42 | val fruit = List("apple", "pear", "orange", "pineapple") 43 | 44 | // inferred parameters' type 45 | //msort(nums)((x, y) => x < y) 46 | //msort(fruit)((x, y) => x.compareTo(y) < 0) 47 | 48 | msort(nums)(Ordering.Int) 49 | msort(nums) 50 | msort(fruit)(Ordering.String) 51 | msort(fruit) 52 | 53 | } -------------------------------------------------------------------------------- /src/main/scala/week5/5-4-higher-order-list-functions.sc: -------------------------------------------------------------------------------- 1 | object lecture4 { 2 | 3 | // 4 | // Common patterns on lists: Transforming 5 | // 6 | 7 | def scaleList(xs: List[Double], factor: Double): List[Double] = xs match { 8 | case Nil => xs 9 | case y :: ys => y * factor :: scaleList(ys, factor) 10 | } 11 | 12 | scaleList(Nil, 2) 13 | scaleList(List(2, 3, 5), 3) 14 | 15 | // A simple definition of 'map' in the List class: 16 | /* 17 | abstract class List[T] { 18 | ... 19 | def map[U](f: T => U): List[U] = this match { 20 | case Nil => this 21 | case x :: xs => f(x) :: xs.map(f) 22 | } 23 | } 24 | */ 25 | 26 | // scaleList rewritten with map 27 | def scaleList2(xs: List[Double], factor: Double) = xs map (x => x * factor) 28 | 29 | scaleList2(Nil, 2) 30 | scaleList2(List(2, 3, 5), 3) 31 | 32 | // Exercise 33 | def squareList(xs: List[Int]): List[Int] = xs match { 34 | case Nil => Nil 35 | case y :: ys => y * y :: squareList(ys) 36 | } 37 | 38 | def squareList2(xs: List[Int]): List[Int] = xs map (x => x * x) 39 | 40 | squareList(List(2, 3, 5)) 41 | squareList2(List(2, 3, 5)) 42 | 43 | // 44 | // Common patterns on lists: Filtering 45 | // 46 | 47 | val nums = List(2, -4, 5, 7, 1) 48 | 49 | def posElems(xs: List[Int]): List[Int] = xs match { 50 | case Nil => xs 51 | case y :: ys => if (y > 0) y :: posElems(ys) else posElems(ys) 52 | } 53 | 54 | posElems(nums) 55 | 56 | // Filtering pattern generalized in the List class: 57 | /* 58 | abstract class List[T] { 59 | ... 60 | def filter(p: T => Boolean): List[T] = this match { 61 | case Nil => this 62 | case x :: xs => if (p(x)) x :: xs.filter(p) else xs.filter(p) 63 | } 64 | } 65 | */ 66 | 67 | def posElems2(xs: List[Int]): List[Int] = xs filter (x => x > 0) 68 | 69 | posElems2(nums) 70 | 71 | } -------------------------------------------------------------------------------- /src/main/scala/week5/5-4-listfun.sc: -------------------------------------------------------------------------------- 1 | object listfun { 2 | 3 | val nums = List(2, -4, 5, 7, 1) 4 | val fruits = List("apple", "pineapple", "orange", "banana") 5 | 6 | nums filter (x => x > 0) 7 | nums filterNot (x => x > 0) 8 | nums partition (x => x > 0) 9 | 10 | nums takeWhile (x => x > 0) 11 | nums dropWhile (x => x > 0) 12 | nums span (x => x > 0) 13 | 14 | // 15 | // Exercises 16 | // 17 | 18 | val data = List("a", "a", "a", "b", "c", "c", "a") 19 | 20 | def pack[T](xs: List[T]): List[List[T]] = xs match { 21 | case Nil => Nil 22 | case x :: xs1 => 23 | val (first, rest) = xs span (y => y == x) 24 | first :: pack(rest) 25 | } 26 | 27 | pack(data) 28 | 29 | def encode[T](xs: List[T]): List[(T, Int)] = 30 | pack(xs) map (ys => (ys.head, ys.length)) 31 | 32 | encode(data) 33 | 34 | } -------------------------------------------------------------------------------- /src/main/scala/week5/5-5-reduction-of-lists.sc: -------------------------------------------------------------------------------- 1 | object reduction { 2 | 3 | val nums = List(1, 2, 3, 4, 5) 4 | 5 | // sum(List(x1, ..., xn)) = 0 + x1 + ... + xn 6 | 7 | def sum(xs: List[Int]): Int = xs match { 8 | case Nil => 0 9 | case y :: ys => y + sum(ys) 10 | } 11 | 12 | sum(nums) 13 | 14 | // product(List(x1, ..., xn)) = 1 * x1 * ... * xn 15 | 16 | def product(xs: List[Int]): Int = xs match { 17 | case Nil => 1 18 | case y :: ys => y * product(ys) 19 | } 20 | 21 | product(nums) 22 | 23 | // 24 | // ReduceLeft 25 | // 26 | // List(x1, ..., xn) reduceLeft op = (...(x1 op x2) op ... ) op xn 27 | 28 | def sumRL(xs: List[Int]) = (0 :: xs) reduceLeft (_ + _) 29 | 30 | def productRL(xs: List[Int]) = (1 :: xs) reduceLeft (_ * _) 31 | 32 | // (_ op _) is the shorter form of ((x, y) => x op y) 33 | 34 | // 35 | // FoldLeft 36 | // 37 | // (List(x1, ..., xn) foldLeft z)(op) = (...(z op x1) op ... ) op xn 38 | 39 | def sumFL(xs: List[Int]) = (xs foldLeft 0) (_ + _) 40 | 41 | def productFL(xs: List[Int]) = (xs foldLeft 1) (_ * _) 42 | 43 | // A possible implementation in the List class: 44 | /* 45 | abstract class List[T] { 46 | def reduceLeft(op: (T, T) => T): T = this match { 47 | case Nil => throw new Error("Nil.reduceLeft") 48 | case x :: xs => (xs foldLeft x)(op) 49 | } 50 | def foldLeft[U](z: U)(op: (U, T) => U): U = this match { 51 | case Nil => z 52 | case x :: xs => (xs foldLeft op(z, x))(op) 53 | } 54 | } 55 | */ 56 | 57 | // 58 | // ReduceRight and FoldRight 59 | // 60 | // List(x1, ..., x{n-1}, xn) reduceRight op = x1 op ( ... (x{n-1} op xn) ... ) 61 | // (List(x1, ..., xn) foldRight acc)(op) = x1 op ( ... (xn op acc) ... ) 62 | 63 | /* 64 | def reduceRight(op: (T, T) => T): T = this match { 65 | case Nil => throw new Error("Nil.reduceRight") 66 | case x :: Nil => x 67 | case x :: xs => op(x, xs.reduceRight(op)) 68 | } 69 | def foldRight[U](z: U)(op: (T, U) => U): U = this match { 70 | case Nil => z 71 | case x :: xs => op(x, (xs foldRight z)(op)) 72 | } 73 | */ 74 | 75 | // Exercise - reformulation of concat with foldRight 76 | 77 | def concat[T](xs: List[T], ys: List[T]): List[T] = 78 | (xs foldRight ys) (_ :: _) 79 | 80 | // It's possible to replace foldRight by foldLeft? No, because the types would not work out 81 | 82 | //def concatFL[T](xs: List[T], ys: List[T]): List[T] = 83 | // (xs foldLeft ys)(_ :: _) 84 | 85 | // Reversing lists with foldLeft (note that the operands are swapped): 86 | // what is the complexity of this implementation of revers? 87 | def reverse[T](xs: List[T]): List[T] = (xs foldLeft List[T]()) ((acc, x) => x :: acc) 88 | 89 | reverse(nums) 90 | 91 | // 92 | // Exercises 93 | // 94 | 95 | def mapFun[T, U](xs: List[T], f: T => U): List[U] = (xs foldRight List[U]()) (???) 96 | 97 | def lengthFun[T](xs: List[T]): Int = (xs foldRight 0) (???) 98 | 99 | } -------------------------------------------------------------------------------- /src/main/scala/week6/maps.sc: -------------------------------------------------------------------------------- 1 | object maps { 2 | val romanNumerals = Map('I' -> 1, 'V' -> 5, 'X' -> 10) 3 | val capitalOfCountry = Map("US" -> "Washington", "Switzerland" -> "Bern") 4 | 5 | capitalOfCountry("US") 6 | 7 | capitalOfCountry get "US" 8 | capitalOfCountry get "Andorra" 9 | 10 | 11 | def showCapital(country: String) = capitalOfCountry.get(country) match { 12 | case Some(capital) => capital 13 | case None => "missing data" 14 | } 15 | 16 | showCapital("US") 17 | showCapital("Andorra") 18 | 19 | val fruit = List("apple", "pear", "orange", "pineapple") 20 | fruit sortWith (_.length < _.length) 21 | fruit.sorted 22 | 23 | fruit groupBy (_.head) 24 | 25 | val cap1 = capitalOfCountry withDefaultValue "" 26 | cap1("Andorra") 27 | } -------------------------------------------------------------------------------- /src/main/scala/week6/mnemonics.sc: -------------------------------------------------------------------------------- 1 | import scala.io.Source 2 | 3 | object mnemonics { 4 | /* read a file of words */ 5 | val in = Source.fromURL("http://lamp.epfl.ch/files/content/sites/lamp/files/teaching/progfun/linuxwords.txt") 6 | 7 | /* create a list and filter all words where *all* their characters are not letters (like dashes) */ 8 | val words = in.getLines.toList filter (word => word forall (chr => chr.isLetter)) 9 | 10 | /* define the map of numbers to letters */ 11 | val nmem = Map('2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ") 12 | 13 | /* invert the map the get a map of letters to digits */ 14 | val charCode: Map[Char, Char] = for ((digit, str) <- nmem; ltr <- str) yield ltr -> digit 15 | 16 | /* define a function that returns the numbers of a given word */ 17 | def wordCode(word: String): String = word.toUpperCase map charCode 18 | 19 | /* group all words of our long list with the same number */ 20 | val wordsForNum: Map[String, Seq[String]] = words groupBy wordCode withDefaultValue Seq() 21 | 22 | /* function that receives a number and finds the words that match it */ 23 | def encode(number: String): Set[List[String]] = 24 | if (number.isEmpty) Set(List()) 25 | else { 26 | for { 27 | split <- 1 to number.length // iterate over the number 28 | word <- wordsForNum(number take split) // get the word before the spilt 29 | rest <- encode(number drop split) //get the words after the split 30 | } yield word :: rest // join the results 31 | }.toSet // pass a set to the for 32 | 33 | /* better print of the results */ 34 | def translate(number: String): Set[String] = encode(number) map (_ mkString " ") 35 | 36 | /* test the translate and print results*/ 37 | translate("7225247386") foreach println 38 | 39 | } -------------------------------------------------------------------------------- /src/main/scala/week6/nqueens.sc: -------------------------------------------------------------------------------- 1 | object nqueens { 2 | def queens(n: Int): Set[List[Int]] = { 3 | def placeQueens(k: Int): Set[List[Int]] = { 4 | if (k == 0) Set(Nil) 5 | else 6 | for { 7 | queens <- placeQueens(k - 1) 8 | col <- 0 until n 9 | if isSafe(col, queens) 10 | } yield col :: queens 11 | } 12 | placeQueens(n) 13 | } 14 | 15 | def isSafe(col: Int, queens: List[Int]): Boolean = { 16 | val row = queens.length 17 | val queensWithRow = (row - 1 to 0 by -1) zip queens 18 | queensWithRow forall { 19 | case (r, c) => col != c && math.abs(col - c) != math.abs(row - r) 20 | } 21 | } 22 | 23 | def show(queens: List[Int]): String = { 24 | val lines = 25 | for (col <- queens.reverse) 26 | yield Vector.fill(queens.length)("* ").updated(col, "X ").mkString 27 | "\n" + (lines mkString "\n") 28 | } 29 | 30 | (queens(8) take 3 map show) mkString "\n" 31 | } -------------------------------------------------------------------------------- /src/main/scala/week6/pairs.sc: -------------------------------------------------------------------------------- 1 | object pairs { 2 | def isPrime(n: Int): Boolean = (2 until n) forall (n % _ != 0) 3 | 4 | val n = 7 5 | 6 | (1 until n) flatMap (i => 7 | (1 until i) map (j => (i, j))) filter (pair => 8 | isPrime(pair._1 + pair._2)) 9 | 10 | for { 11 | i <- 1 until n 12 | j <- 1 until i 13 | if isPrime(i + j) 14 | } yield (i, j) 15 | 16 | def scalarProduct(xs: Vector[Double], ys: Vector[Double]): Double = 17 | (for ((x, y) <- xs zip ys) yield x * y).sum 18 | } -------------------------------------------------------------------------------- /src/main/scala/week6/polynomials.sc: -------------------------------------------------------------------------------- 1 | object polynomials { 2 | 3 | class Poly(val terms0: Map[Int, Double]) { 4 | 5 | def this(bindings: (Int, Double)*) = this(bindings.toMap) 6 | 7 | val terms = terms0 withDefaultValue 0.0 8 | 9 | /* def + (other: Poly) = new Poly(terms ++ (other.terms map adjust)) 10 | 11 | private def adjust(term: (Int, Double)): (Int, Double) = { 12 | val (exp, coeff) = term 13 | exp -> (coeff + terms(exp)) 14 | } */ 15 | 16 | def +(other: Poly) = new Poly((other.terms foldLeft terms) (addTerm)) 17 | 18 | private def addTerm(terms: Map[Int, Double], term: (Int, Double)): Map[Int, Double] = { 19 | val (exp, coeff) = term 20 | terms + (exp -> (coeff + terms(exp))) 21 | } 22 | 23 | override def toString = 24 | (for ((exp, coeff) <- terms.toList.sorted.reverse) 25 | yield coeff + "x^" + exp) mkString " + " 26 | } 27 | 28 | val p1 = new Poly(1 -> 2.0, 3 -> 4.0, 5 -> 6.2) 29 | val p2 = new Poly(Map(0 -> 3.0, 3 -> 7.0)) 30 | p1 + p2 31 | } -------------------------------------------------------------------------------- /src/main/scala/week6/test.sc: -------------------------------------------------------------------------------- 1 | object test { 2 | val xs = Array(1, 2, 3, 44) 3 | xs map (x => x * 2) 4 | 5 | val s = "Hello World" 6 | s filter (c => c.isUpper) 7 | 8 | s exists (c => c.isUpper) 9 | s forall (c => c.isUpper) 10 | 11 | val pairs = List(1, 2, 3) zip s 12 | pairs.unzip 13 | 14 | s flatMap (c => List('.', c)) 15 | 16 | xs.sum 17 | xs.max 18 | 19 | (1 to 5) flatMap (x => (1 to 10) map (y => (x, y))) 20 | 21 | def scalarProduct(xs: Vector[Double], ys: Vector[Double]): Double = 22 | (xs zip ys).map { case (x, y) => x * y }.sum 23 | 24 | } --------------------------------------------------------------------------------