Search code examples
scalascala-2.8typeclassscala-2.7

Looking for example of type class usage that will work in Scala 2.7.7 and 2.8 scripts


Hi I'm looking for a quick example of type class usage in Scala that will work in both 2.7.7 and 2.8 environments.

All of the examples that I've seen only work in 2.8, but I've been told that type classes are implementable in 2.7.7 as well.

The only other requirement is that the usage must be able to work in a script.

Any examples appreciated! Thanks


Solution

  • I went with a solution along these lines:

    //---------- Classes without needed behavior
    case class Point(x: Double, y: Double)
    trait Shape {}
    case class Circle(center: Point, radius: Double) extends Shape {}
    case class Rectangle(lowerLeft: Point, upperRight: Point) extends Shape {}
    
    
    val circle = Circle(Point(1.0, 2.0), 5.0)
    val rectangle = Rectangle(Point(-2.0, -1.0), Point(4.0, 5.0))
    
    
    //----------- Support for new behavior I want to add
    
    // Create exception to handle non supported subclasses
    case class NewMethodNotSupported(a: Any)
        extends RuntimeException(a.toString + ".newMethod() not supported")
    
    class NewBehavior(shape: Shape) {
        def newMethod() = shape match {
            case c: Circle => doMethod(c)
            case r: Rectangle => doMethod(r)
            case _ => throw NewMethodNotSupported(shape)
        }
        private
        def doMethod(s: Shape) = println(s) // print to standard out.
    }
    
    object NewBehavior {
        // invoked by the compiler
        implicit def shapeToNewBehavior(s: Shape) = new NewBehavior(s)
    }
    
    // bring the implicit method in scope
    import NewBehavior._
    // --------- End of new behavior support        
    
    
    // Test behavior support:
    println("Test that new behavior is added:")
    circle.newMethod()
    rectangle.newMethod()
    
    // Create a non supported shape class
    case class Triangle(vertex1: Point,
            vertex2: Point, vertex3: Point) extends Shape {}
    
    val triangle = Triangle(Point(-1.0,0.0), Point(1.0,0.0), Point(0.0,1.0))
    
    // Catch exception thrown by trying to call method from unsupported shape
    try{    
        println("\nTest method call from unsupported shape:")
        triangle.newMethod()
    } catch {
        case dns: NewMethodNotSupported => println(dns); System.exit(-1)
        case unknown => println("Uknown exception " + unknown); System.exit(-1)
    }