Sample run of chapter's interpreter examples
// In file implicits/Swing1.scala val button = new JButton button.addActionListener( new ActionListener { def actionPerformed(event: ActionEvent) { println("pressed!") } } )
// In file implicits/Swing2.scala button.addActionListener( // Type mismatch! (_: ActionEvent) => println("pressed!") )
// In file implicits/Swing2.scala implicit def function2ActionListener(f: ActionEvent => Unit) = new ActionListener { def actionPerformed(event: ActionEvent) = f(event) }
button.addActionListener( function2ActionListener( (_: ActionEvent) => println("pressed!") ) )
// Now this works button.addActionListener( (_: ActionEvent) => println("pressed!") )
// In file implicits/Misc.scala implicit def intToString(x: Int) = x.toString
object Dollar { implicit def dollarToEuro(x: Dollar): Euro = ... } class Dollar { ... }
object MyConversions { implicit def stringWrapper(s: String): IndexedSeq[Char] = ... implicit def intToString(x: Int): String = ... }
import MyConversions.stringWrapper ... // code making use of stringWrapper
scala> val i: Int = 3.5 <console>:4: error: type mismatch; found : Double(3.5) required: Int val i: Int = 3.5 ^
scala> implicit def doubleToInt(x: Double) = x.toInt doubleToInt: (x: Double)Int scala> val i: Int = 3.5 i: Int = 3
val i: Int = doubleToInt(3.5)
// In file implicits/Misc.scala implicit def int2double(x: Int): Double = x.toDouble
class Rational(n: Int, d: Int) { ... def + (that: Rational): Rational = ... def + (that: Int): Rational = ... }
scala> val oneHalf = new Rational(1, 2) oneHalf: Rational = 1/2 scala> oneHalf + oneHalf res0: Rational = 1/1 scala> oneHalf + 1 res1: Rational = 3/2
scala> 1 + oneHalf <console>:6: error: overloaded method value + with alternatives (Double)Double <and> ... cannot be applied to (Rational) 1 + oneHalf ^
scala> implicit def intToRational(x: Int) = | new Rational(x, 1) intToRational: (x: Int)Rational
scala> 1 + oneHalf res2: Rational = 3/2
intToRational(1) + oneHalf
// In file implicits/Misc.scala Map(1 -> "one", 2 -> "two", 3 -> "three")
package scala object Predef { class ArrowAssoc[A](x: A) { def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y) } implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x) ... }
class PreferredPrompt(val preference: String)
object Greeter { def greet(name: String)(implicit prompt: PreferredPrompt) { println("Welcome, "+ name +". The system is ready.") println(prompt.preference) } }
scala> val bobsPrompt = new PreferredPrompt("relax> ") bobsPrompt: PreferredPrompt = PreferredPrompt@74a138 scala> Greeter.greet("Bob")(bobsPrompt) Welcome, Bob. The system is ready. relax>
object JoesPrefs { implicit val prompt = new PreferredPrompt("Yes, master> ") }
scala> Greeter.greet("Joe") <console>:10: error: could not find implicit value for parameter prompt: PreferredPrompt Greeter.greet("Joe") ^
scala> import JoesPrefs._ import JoesPrefs._ scala> Greeter.greet("Joe") Welcome, Joe. The system is ready. Yes, master>
class PreferredPrompt(val preference: String) class PreferredDrink(val preference: String) object Greeter { def greet(name: String)(implicit prompt: PreferredPrompt, drink: PreferredDrink) { println("Welcome, "+ name +". The system is ready.") print("But while you work, ") println("why not enjoy a cup of "+ drink.preference +"?") println(prompt.preference) } } object JoesPrefs { implicit val prompt = new PreferredPrompt("Yes, master> ") implicit val drink = new PreferredDrink("tea") }
scala> Greeter.greet("Joe") <console>:14: error: could not find implicit value for parameter prompt: PreferredPrompt Greeter.greet("Joe") ^
scala> import JoesPrefs._ import JoesPrefs._
scala> Greeter.greet("Joe")(prompt, drink) Welcome, Joe. The system is ready. But while you work, why not enjoy a cup of tea? Yes, master>
scala> Greeter.greet("Joe") Welcome, Joe. The system is ready. But while you work, why not enjoy a cup of tea? Yes, master>
// In file implicits/Misc.scala def maxListUpBound[T <: Ordered[T]](elements: List[T]): T = elements match { case List() => throw new IllegalArgumentException("empty list!") case List(x) => x case x :: rest => val maxRest = maxListUpBound(rest) if (x > maxRest) x else maxRest }
// In file implicits/MaxList1.scala def maxListImpParm[T](elements: List[T]) (implicit orderer: T => Ordered[T]): T = elements match { case List() => throw new IllegalArgumentException("empty list!") case List(x) => x case x :: rest => val maxRest = maxListImpParm(rest)(orderer) if (orderer(x) > maxRest) x else maxRest }
scala> maxListImpParm(List(1,5,10,3)) res9: Int = 10 scala> maxListImpParm(List(1.5, 5.2, 10.7, 3.14159)) res10: Double = 10.7 scala> maxListImpParm(List("one", "two", "three")) res11: java.lang.String = two
def maxListPoorStyle[T](elements: List[T]) (implicit orderer: (T, T) => Boolean): T
// In file implicits/Misc.scala def maxList[T](elements: List[T]) (implicit orderer: T => Ordered[T]): T = elements match { case List() => throw new IllegalArgumentException("empty list!") case List(x) => x case x :: rest => val maxRest = maxList(rest) // (orderer) is implicit if (x > maxRest) x // orderer(x) is implicit else maxRest }
// In file implicits/Misc.scala def maxList[T](elements: List[T]) (implicit converter: T => Ordered[T]): T = // same body...
// In file implicits/Misc.scala def maxList[T](elements: List[T]) (implicit iceCream: T => Ordered[T]): T = // same body...
// In file implicits/MaxList2.scala def maxList[T <% Ordered[T]](elements: List[T]): T = elements match { case List() => throw new IllegalArgumentException("empty list!") case List(x) => x case x :: rest => val maxRest = maxList(rest) // (orderer) is implicit if (x > maxRest) x // orderer(x) is implicit else maxRest }
implicit def identity[A](x: A): A = x
scala> def printLength(seq: Seq[Int]) = println(seq.length) printLength: (seq: Seq[Int])Unit scala> implicit def intToRange(i: Int) = 1 to i intToRange: (i: Int)scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne scala> implicit def intToDigits(i: Int) = | i.toString.toList.map(_.toInt) intToDigits: (i: Int)List[Int] scala> printLength(12) <console>:21: error: type mismatch; found : Int(12) required: Seq[Int] Note that implicit conversions are not applicable because they are ambiguous: ...
val cba = "abc".reverse
// In file implicits/mocha.scala object Mocha extends Application { class PreferredDrink(val preference: String) implicit val pref = new PreferredDrink("mocha") def enjoy(name: String)(implicit drink: PreferredDrink) { print("Welcome, "+ name) print(". Enjoy a ") print(drink.preference) println("!") } enjoy("reader") }
$ scalac -Xprint:typer mocha.scala [[syntax trees at end of typer]]// Scala source: mocha.scala package <empty> { final object Mocha extends java.lang.Object with Application with ScalaObject { // ... private[this] val pref: Mocha.PreferredDrink = new Mocha.this.PreferredDrink("mocha"); implicit <stable> <accessor> def pref: Mocha.PreferredDrink = Mocha.this.pref; def enjoy(name: String) (implicit drink: Mocha.PreferredDrink): Unit = { scala.this.Predef.print("Welcome, ".+(name)); scala.this.Predef.print(". Enjoy a "); scala.this.Predef.print(drink.preference); scala.this.Predef.println("!") }; Mocha.this.enjoy("reader")(Mocha.this.pref) } }
scala> val chars: List[Char] = "xyz" <console>:19: error: type mismatch; found : java.lang.String("xyz") required: List[Char] val chars: List[Char] = "xyz" ^
scala> val chars: List[Char] = wrapString("xyz") <console>:19: error: type mismatch; found : scala.collection.immutable.WrappedString required: List[Char] val chars: List[Char] = wrapString("xyz") ^
Mocha.this.enjoy("reader")(Mocha.this.pref)
For more information about Programming in Scala, Second Edition (the "Stairway Book"), please visit: http://www.artima.com/shop/programming_in_scala_2ed and: |
Copyright © 2007-2010 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. |