Abstract member types, Parameterized types and Pattern Matching.



Introduction
Make your Iterable stack object visitable using Trait. This implementation varies from the implementation in  previous post . This solution uses features like Abstract member type, Type Parameterization & Pattern Matching in Scala. This example illustrates how Abstract types and parameterized types can be used in tandem. PointVisitor encapsulates the details of Specialized Point Structures. 


Program

package com.rajeshpatkar
object Program {
  def main(args: Array[String]): Unit = {
    val p1 = Point2D(1,2)
    val p2 = Point3D(5,6,7)
    val p3 = PointPolar(1,34)
    val s1 = new PStack();
    s1 < p1 < p2 < p3 ~ ;
    s1.visit(_*3).visit(_*5).visit(_-2);
  }
}

abstract class Point
case class Point2D(val x:Int , val y:Int) extends Point
case class Point3D(val x:Int,val y:Int,val z:Int) extends Point
case class PointPolar(val r:Int ,val theta:Int) extends Point

trait Visitable[T] extends Iterable[T]{
 type G;
 def visit(p:G):Visitable[T] = {foreach(pattern(_,p));this}
 def pattern(P:T,p:G);
}

trait PointVisitor extends Visitable[Point]
{
  type G = (Int)=>(Int)
  def pattern(P:Point,p:G) = P match {
                  case Point2D(x,y) => 
                       println("x = "+ p(x)+ " y = " + p(y))
                  case Point3D(x,y,z) => 
                       println("x = "+ p(x) +" y = "+ p(y) +" z = "+ p(z))
                  case PointPolar(r,theta) => 
                       println("r = " + p(r) + " theta = "+ p(theta))
                  case _ => println("Match not found")
  }
  override def visit(p:G):PointVisitor = {super.visit(p);this}
}

abstract class Stack[T] extends Visitable[T]{
  
  class Node (val value : T , val next : Node);
  var h : Node = null;
  def < ( value : T ) :Stack[T]= { h = new Node(value,h); this }
  def > (op: (Option[T])=>Unit):Stack[T] = { 
         var value:Option[T] = if(h == null) None
                     else {
                            val t = h.value
                            h = h.next
                            Some(t)
                     }  
         op(value)           
         println("Value Popped -->" + value)     
         this 
  }
  def ~ () : Stack[T] = { 
                       println("Printing Stack...")
                       foreach(println)
                       this;
  }
  override def iterator():Iterator[T] = {
                              var data = List[T]()
                              var temp = h;
                              while(temp != null){
                                  data = temp.value::data
                                  temp=temp.next
                              }
                              data.iterator
  }                                             
 }


case class PStack extends Stack[Point] with PointVisitor


Output

Point2D(1,2)
Point3D(5,6,7)
PointPolar(1,34)
x = 3 y = 6
x = 15 y = 18 z = 21
r = 3 theta = 102
x = 5 y = 10
x = 25 y = 30 z = 35
r = 5 theta = 170
x = -1 y = 0
x = 3 y = 4 z = 5
r = -1 theta = 32


copyright ©Rajesh Patkar, All rights reserved.

Comments

Popular posts from this blog

Potter Metaphor.

Chrome

Harikavach ( Level 3 )