Code Examples for

Programming in Scala, Fifth Edition

Return to chapter index

6 Functional Objects

Sample run of chapter's interpreter examples

6.1 A specification for class Rational


scala> val oneHalf = Rational(1, 2) val oneHalf: Rational = 1/2 scala> val twoThirds = Rational(2, 3) val twoThirds: Rational = 2/3 scala> (oneHalf / 7) + (1 - twoThirds) val res0: Rational = 17/42

6.2 Constructing a Rational


class Rational(n: Int, d: Int)
// In file functional-objects/ex1/Rational.scala class Rational(n: Int, d: Int): println("Created " + n + "/" + d)
scala> new Rational(1, 2) Created 1/2 val res0: Rational = Rational@6121a7dd
scala> Rational(1, 2) Created 1/2 val res1: Rational = Rational@5dc7841c

6.3 Reimplementing the toString method


// In file functional-objects/ex2/Rational.scala class Rational(n: Int, d: Int): override def toString = s"n/d"
scala> val x = Rational(1, 3) x: Rational = 1/3 scala> val y = Rational(5, 7) y: Rational = 5/7

6.4 Checking preconditions


scala> Rational(5, 0) // 5/0 val res1: Rational = 5/0
// In file functional-objects/ex4/Rational.scala class Rational(n: Int, d: Int): require(d != 0) override def toString = s"n/d"

6.5 Adding fields


class Rational(n: Int, d: Int): // This won't compile require(d != 0) override def toString = s"n/d" def add(that: Rational): Rational = Rational(n * that.d + that.n * d, d * that.d)
5 | Rational(n * that.d + that.n * d, d * that.d) | ^^^^^^ |value n in class Rational cannot be accessed as a member | of (that : Rational) from class Rational. 5 | Rational(n * that.d + that.n * d, d * that.d) | ^^^^^^ |value d in class Rational cannot be accessed as a member | of (that : Rational) from class Rational. 5 | Rational(n * that.d + that.n * d, d * that.d) | ^^^^^^ |value d in class Rational cannot be accessed as a member | of (that : Rational) from class Rational.
// In file functional-objects/ex5/Rational.scala class Rational(n: Int, d: Int): require(d != 0) val numer: Int = n val denom: Int = d override def toString = s"numer/denom" def add(that: Rational): Rational = Rational( numer * that.denom + that.numer * denom, denom * that.denom )
val oneHalf = Rational(1, 2) // 1/2 val twoThirds = Rational(2, 3) // 2/3 oneHalf.add(twoThirds) // 7/6
val r = Rational(1, 2) // 1/2 r.numer // 1 r.denom // 2

6.6 Self references


// In file functional-objects/ex6/Rational.scala def lessThan(that: Rational) = this.numer * that.denom < that.numer * this.denom
// In file functional-objects/ex6/Rational.scala def max(that: Rational) = if this.lessThan(that) then that else this

6.7 Auxiliary constructors


// In file functional-objects/ex7/Rational.scala class Rational(n: Int, d: Int): require(d != 0) val numer: Int = n val denom: Int = d def this(n: Int) = this(n, 1) // auxiliary constructor override def toString = s"numer/denom" def add(that: Rational): Rational = Rational( numer * that.denom + that.numer * denom, denom * that.denom )
val y = Rational(3) // 3/1

6.8 Private fields and methods


Rational(66, 42) // 66/42
// In file functional-objects/ex8/Rational.scala class Rational(n: Int, d: Int): require(d != 0) private val g = gcd(n.abs, d.abs) val numer = n / g val denom = d / g def this(n: Int) = this(n, 1) def add(that: Rational): Rational = Rational( numer * that.denom + that.numer * denom, denom * that.denom ) override def toString = s"numer/denom" private def gcd(a: Int, b: Int): Int = if b == 0 then a else gcd(b, a % b)
Rational(66, 42) // 11/7

6.9 Defining operators


x + y
x.add(y)
x add y
// In file functional-objects/ex9/Rational.scala class Rational(n: Int, d: Int): require(d != 0) private val g = gcd(n.abs, d.abs) val numer = n / g val denom = d / g def this(n: Int) = this(n, 1) def + (that: Rational): Rational = Rational( numer * that.denom + that.numer * denom, denom * that.denom ) def * (that: Rational): Rational = Rational(numer * that.numer, denom * that.denom) override def toString = s"numer/denom" private def gcd(a: Int, b: Int): Int = if b == 0 then a else gcd(b, a % b)
val x = Rational(1, 2) // 1/2 val y = Rational(2, 3) // 2/3 x + y // 7/6
x.+(y) // 7/6
x + x * y // 5/6 (x + x) * y // 2/3 x + (x * y) // 5/6

6.10 Identifiers in Scala

6.11 Method overloading


// In file givens/rational-compare.scala class Rational(n: Int, d: Int): require(d != 0) private val g = gcd(n.abs, d.abs) val numer = n / g val denom = d / g def this(n: Int) = this(n, 1) def + (that: Rational): Rational = Rational( numer * that.denom + that.numer * denom, denom * that.denom ) def + (i: Int): Rational = Rational(numer + i * denom, denom) def - (that: Rational): Rational = Rational( numer * that.denom - that.numer * denom, denom * that.denom ) def - (i: Int): Rational = Rational(numer - i * denom, denom) def * (that: Rational): Rational = Rational(numer * that.numer, denom * that.denom) def * (i: Int): Rational = Rational(numer * i, denom) def / (that: Rational): Rational = Rational(numer * that.denom, denom * that.numer) def / (i: Int): Rational = Rational(numer, denom * i) override def toString = s"numer/denom" private def gcd(a: Int, b: Int): Int = if b == 0 then a else gcd(b, a % b)
val r = Rational(2, 3) // 2/3 r * r // 4/9 r * 2 // 4/3

6.12 Extension methods


scala> 2 * r 1 |2 * r |^^^ |None of the overloaded alternatives of method * in | class Int with types | (x: Double): Double | (x: Float): Float | (x: Long): Long | (x: Int): Int | (x: Char): Int | (x: Short): Int | (x: Byte): Int |match arguments ((r : Rational))
extension (x: Int) def + (y: Rational) = Rational(x) + y def - (y: Rational) = Rational(x) - y def * (y: Rational) = Rational(x) * y def / (y: Rational) = Rational(x) / y
val r = Rational(2,3) // 2/3 2 * r // 4/3

6.13 A word of caution

6.14 Conclusion

For more information about Programming in Scala, Fifth Edition (the "Stairway Book"), please visit:

http://www.artima.com/shop/programming_in_scala_5ed

and:

http://booksites.artima.com/programming_in_scala_5ed

Copyright © 2007-2020 Artima, Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.