SlideShare a Scribd company logo
Implicit conversions
Magic?
  String s = "!em esreveR";
  System.out.println(s.reverse());




val s: java.lang.String = "!em esreveR"
println(s.reverse)



=> Reverse me!
Magic?
  String s = "!em esreveR";
  System.out.println(s.reverse());




val s: java.lang.String = "!em esreveR"
println(s.reverse)
println(stringWrapper(s).reverse)


=> Reverse me!
Magic?
  String s = "!em esreveR";
  System.out.println(s.reverse());




val s: java.lang.String = "!em esreveR"
println(s.reverse)
println(stringWrapper(s).reverse)
println(new runtime.RichString(s).reverse)

=> Reverse me!
implicit



implicit def stringWrapper(x: String) =
       new runtime.RichString(x)
scala.runtime.RichString
def toArray : Array[Char]
def toBoolean : Boolean
def toByte : Byte
def toDouble : Double
def toFloat : Float
def toInt : Int
def toLong : Long
def toShort : Short
def r : Regex
def lines : Iterator[java.lang.String]
def * (n : Int) : java.lang.String
...
scala.Predef
A set of implicits              Other nice functions
   byteWrapper(x: Byte)
   shortWrapper(x: Short)         println(...)
   intWrapper(x: Int)
   charWrapper(c: Char)           readLine(...)
   longWrapper(x: Long)
   floatWrapper(x: Float)         error(...)
   doubleWrapper(x: Double)       ...
   booleanWrapper(x: Boolean)
   stringWrapper(x: String)
   stringBuilderWrapper(x :
       StringBuilder)
   ...
Map and ArrowAssoc
val myMap: Map[Int, String] =

  Map(1 -> "one", 2 -> "two")
Map and ArrowAssoc
val myMap: Map[Int, String] =

  Map(1 -> "one", 2 -> "two")




  Map.apply(Tuple2(1, "one"), Tuple2(2, "two"))
Map and ArrowAssoc
val myMap: Map[Int, String] =

  Map(1 -> "one", 2 -> "two")




  Map((1, "one"), (2, "two"))
Map and ArrowAssoc
val myMap: Map[Int, String] =

  Map(1 -> "one", 2 -> "two")

  Map(any2ArrowAssoc(1) -> "one",
      any2ArrowAssoc(2) -> "two")

  Map((1, "one"), (2, "two"))
scala.Predef.ArrowAssoc
implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] =
 new ArrowAssoc(x)


class ArrowAssoc[A](x: A) {
  def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
}



val myMap = Map(1 -> "one", 2 -> "two")
Implicit rules!
Marking Rule: Only definitions marked implicit are available.
Scope Rule: An inserted implicit conversion must be in scope as a
  single identifier, or be associated with the source or target type of the
  conversion.
Non-Ambiguity Rule: An implicit conversion is only inserted if there is no
  other possible conversion to insert.
One-at-a-time Rule: Only one implicit is tried.
Explicits-First Rule: Whenever code type checks as it is written, no
  implicits are attempted.

More Related Content

2.3 implicits

  • 2. Magic? String s = "!em esreveR"; System.out.println(s.reverse()); val s: java.lang.String = "!em esreveR" println(s.reverse) => Reverse me!
  • 3. Magic? String s = "!em esreveR"; System.out.println(s.reverse()); val s: java.lang.String = "!em esreveR" println(s.reverse) println(stringWrapper(s).reverse) => Reverse me!
  • 4. Magic? String s = "!em esreveR"; System.out.println(s.reverse()); val s: java.lang.String = "!em esreveR" println(s.reverse) println(stringWrapper(s).reverse) println(new runtime.RichString(s).reverse) => Reverse me!
  • 5. implicit implicit def stringWrapper(x: String) = new runtime.RichString(x)
  • 6. scala.runtime.RichString def toArray : Array[Char] def toBoolean : Boolean def toByte : Byte def toDouble : Double def toFloat : Float def toInt : Int def toLong : Long def toShort : Short def r : Regex def lines : Iterator[java.lang.String] def * (n : Int) : java.lang.String ...
  • 7. scala.Predef A set of implicits Other nice functions byteWrapper(x: Byte) shortWrapper(x: Short) println(...) intWrapper(x: Int) charWrapper(c: Char) readLine(...) longWrapper(x: Long) floatWrapper(x: Float) error(...) doubleWrapper(x: Double) ... booleanWrapper(x: Boolean) stringWrapper(x: String) stringBuilderWrapper(x : StringBuilder) ...
  • 8. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two")
  • 9. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map.apply(Tuple2(1, "one"), Tuple2(2, "two"))
  • 10. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map((1, "one"), (2, "two"))
  • 11. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map(any2ArrowAssoc(1) -> "one", any2ArrowAssoc(2) -> "two") Map((1, "one"), (2, "two"))
  • 12. scala.Predef.ArrowAssoc implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x) class ArrowAssoc[A](x: A) { def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y) } val myMap = Map(1 -> "one", 2 -> "two")
  • 13. Implicit rules! Marking Rule: Only definitions marked implicit are available. Scope Rule: An inserted implicit conversion must be in scope as a single identifier, or be associated with the source or target type of the conversion. Non-Ambiguity Rule: An implicit conversion is only inserted if there is no other possible conversion to insert. One-at-a-time Rule: Only one implicit is tried. Explicits-First Rule: Whenever code type checks as it is written, no implicits are attempted.