/* * Copyright (C) 2007-2008 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. * * Automatically generated Scala interpreter transcript from: * * Programming in Scala (First Edition, Version 6) * by Martin Odersky, Lex Spoon, Bill Venners * * http://booksites.artima.com/programming_in_scala */ scala> trait RationalTrait { val numerArg: Int val denomArg: Int require(denomArg != 0) private val g = gcd(numerArg, denomArg) val numer = numerArg / g val denom = denomArg / g private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b) override def toString = numer +"/"+ denom } defined trait RationalTrait scala> val x = 2 x: Int = 2 scala> new RationalTrait { val numerArg = 1 * x val denomArg = 2 * x } java.lang.IllegalArgumentException: requirement failed at scala.Predef$.require(Predef.scala:107) at RationalTrait$class.$init$(:7) at $anon$1.(:7) at .(:7) at .() at RequestResult$.(:3) at RequestResult$.() at RequestResult$result() at sun.reflect.NativeMethodAccessorImpl.invoke0... scala> new { val numerArg = 1 * x val denomArg = 2 * x } with RationalTrait res1: java.lang.Object with RationalTrait = 1/2 scala> new { val numerArg = 1 val denomArg = this.numerArg * 2 } with RationalTrait :8: error: value numerArg is not a member of object $iw val denomArg = this.numerArg * 2 ^ scala> object Demo { val x = { println("initializing x"); "done" } } defined module Demo scala> Demo initializing x res3: Demo.type = Demo$@c92844 scala> Demo.x res4: java.lang.String = done scala> object Demo { lazy val x = { println("initializing x"); "done" } } defined module Demo scala> Demo res5: Demo.type = Demo$@e6eb5e scala> Demo.x initializing x res6: java.lang.String = done scala> trait LazyRationalTrait { val numerArg: Int val denomArg: Int lazy val numer = numerArg / g lazy val denom = denomArg / g override def toString = numer +"/"+ denom private lazy val g = { require(denomArg != 0) gcd(numerArg, denomArg) } private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b) } defined trait LazyRationalTrait scala> val x = 2 x: Int = 2 scala> new LazyRationalTrait { val numerArg = 1 * x val denomArg = 2 * x } res7: java.lang.Object with LazyRationalTrait = 1/2 scala> class Food abstract class Animal { type SuitableFood <: Food def eat(food: SuitableFood) } class Grass extends Food class Cow extends Animal { type SuitableFood = Grass override def eat(food: Grass) {} } defined class Food defined class Animal defined class Grass defined class Cow scala> class Fish extends Food defined class Fish scala> val bessy: Animal = new Cow bessy: Animal = Cow@13eb5b scala> bessy eat (new Fish) :10: error: type mismatch; found : Fish required: bessy.SuitableFood bessy eat (new Fish) ^ scala> class DogFood extends Food class Dog extends Animal { type SuitableFood = DogFood override def eat(food: DogFood) {} } defined class DogFood defined class Dog scala> val bessy = new Cow bessy: Cow = Cow@227e59 scala> val lassie = new Dog lassie: Dog = Dog@32bf23 scala> lassie eat (new bessy.SuitableFood) :10: error: type mismatch; found : Grass required: DogFood lassie eat (new bessy.SuitableFood) ^ scala> val bootsie = new Dog bootsie: Dog = Dog@ff0b72 scala> class Outer { class Inner } defined class Outer scala> val o1 = new Outer val o2 = new Outer o1: Outer = Outer@109ce0 o2: Outer = Outer@ab3a42 scala> new o1.Inner res11: o1.Inner = Outer$Inner@aee600 scala> new Outer#Inner :6: error: Outer is not a legal prefix for a constructor new Outer#Inner ^ scala> object Direction extends Enumeration { val North = Value("North") val East = Value("East") val South = Value("South") val West = Value("West") } defined module Direction scala> for (d <- Direction) print(d +" ") North East South West scala> Direction.East.id res14: Int = 1 scala> Direction(1) res15: Direction.Value = East scala> abstract class CurrencyZone { type Currency <: AbstractCurrency def make(x: Long): Currency abstract class AbstractCurrency { val amount: Long def designation: String def + (that: Currency): Currency = make(this.amount + that.amount) def * (x: Double): Currency = make((this.amount * x).toLong) def from(other: CurrencyZone#AbstractCurrency): Currency = make(Math.round( other.amount.toDouble * Converter.exchangeRate (other.designation)(this.designation))) private def decimals(n: Long): Int = if (n == 1) 0 else 1 + decimals(n / 10) override def toString = ((amount.toDouble / CurrencyUnit.amount.toDouble) formatted ("%."+ decimals(CurrencyUnit.amount) +"f") +" "+ designation) } val CurrencyUnit: Currency } object US extends CurrencyZone { abstract class Dollar extends AbstractCurrency { def designation = "USD" } type Currency = Dollar def make(cents: Long) = new Dollar { val amount = cents } val Cent = make(1) val Dollar = make(100) val CurrencyUnit = Dollar } object Europe extends CurrencyZone { abstract class Euro extends AbstractCurrency { def designation = "EUR" } type Currency = Euro def make(cents: Long) = new Euro { val amount = cents } val Cent = make(1) val Euro = make(100) val CurrencyUnit = Euro } object Japan extends CurrencyZone { abstract class Yen extends AbstractCurrency { def designation = "JPY" } type Currency = Yen def make(yen: Long) = new Yen { val amount = yen } val Yen = make(1) val CurrencyUnit = Yen } object Converter { var exchangeRate = Map( "USD" -> Map("USD" -> 1.0 , "EUR" -> 0.7596, "JPY" -> 1.211 , "CHF" -> 1.223), "EUR" -> Map("USD" -> 1.316 , "EUR" -> 1.0 , "JPY" -> 1.594 , "CHF" -> 1.623), "JPY" -> Map("USD" -> 0.8257, "EUR" -> 0.6272, "JPY" -> 1.0 , "CHF" -> 1.018), "CHF" -> Map("USD" -> 0.8108, "EUR" -> 0.6160, "JPY" -> 0.982 , "CHF" -> 1.0 ) ) } defined class CurrencyZone defined module US defined module Europe defined module Japan defined module Converter scala> Japan.Yen from US.Dollar * 100 res16: Japan.Currency = 12110 JPY scala> Europe.Euro from res16 res17: Europe.Currency = 75.95 EUR scala> US.Dollar from res17 res18: US.Currency = 99.95 USD scala> US.Dollar * 100 + res18 res19: US.Currency = 199.95 USD scala> US.Dollar + Europe.Euro :7: error: type mismatch; found : Europe.Euro required: US.Currency US.Dollar + Europe.Euro ^