Monday, March 17, 2014

Multiple Context Bounds

def managed[A : Resource : Manifest](opener : => A) : ManagedResource[A] = new DefaultManagedResource(opener)
means
def managed[A](opener : => A)(implicit r: Resource[A], m: Manifest[A]) : ManagedResource[A] = new DefaultManagedResource(opener)

----
Using a simpler example to illustrate:
def method[T : Manifest](param : T) : ResultType[T] = ...
The notation T : Manifest means that there is a context bound. Elsewhere in your program, in scope, must be defined a singleton or value of type Manifest[T] that's marked as an implicit.
This is achieved by the compiler rewriting the method signature to use a second (implicit) parameter block:

def method[T](param : T)(implicit x$1 : Manifest[T]) : ResultType[T] = ...

reference: http://stackoverflow.com/questions/3798296/in-type-parameter

==========================================================================

http://docs.scala-lang.org/tutorials/tour/implicit-parameters.html
http://docs.scala-lang.org/sips/completed/implicit-classes.html (implicit classes)

In the following example we define a method sum which computes the sum of a list of elements using the monoid’s add and unit operations. Please note that implicit values can not be top-level, they have to be members of a template.
  1. abstract class SemiGroup[A] {
  2. def add(x: A, y: A): A
  3. }
  4. abstract class Monoid[A] extends SemiGroup[A] {
  5. def unit: A
  6. }
  7. object ImplicitTest extends App {
  8. implicit object StringMonoid extends Monoid[String] {
  9. def add(x: String, y: String): String = x concat y
  10. def unit: String = ""
  11. }
  12. implicit object IntMonoid extends Monoid[Int] {
  13. def add(x: Int, y: Int): Int = x + y
  14. def unit: Int = 0
  15. }
  16. def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
  17. if (xs.isEmpty) m.unit
  18. else m.add(xs.head, sum(xs.tail))
  19. println(sum(List(1, 2, 3)))
  20. println(sum(List("a", "b", "c")))
  21. }
Here is the output of the Scala program:
  1. 6
  2. abc

No comments: