pattern matching on tuples

View: New views
4 Messages — Rating Filter:   Alert me  

pattern matching on tuples

by stan-32 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Hello,

abstract class Shape
case class Circle(radius:Int) extends Shape
case class Rectangle(width:Int, height:Int) extends Shape

def area(shape:Shape):Double = shape match {
       case Circle(radius) => 3.14*radius*radius
       case Rectangle(width, height) => width*height
}

The code above  does pattern matching on of input parameter type shape:Shape. In this case it is likely to use tuples to represent data in Rectangle and Circle classes.
Tuple2[String, Int]("circle", radius)
Tuple3[String, Int, Int]("rectangle", width, height)
So finally I want to write a code which does pattern matching on tuple. Here's how it is done with erlang

area({rect,Width,Height})->Width*Height;
area({circle,Radius})->3.14*Radius*Radius.


Is it possible to have something close in scala?  To be specific I mean this


def area(shape:Tuple):Double = shape match {
       case ("circle", radius) => 3.14*radius*radius
       case ("rectangle", width, height) => width*height
}


Thank you.
Nazar

Re: pattern matching on tuples

by csar :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message



On Jan 10, 2008 4:33 PM, Nazar Stasiv <nstasiv@...> wrote:
Hello,

abstract class Shape
case class Circle(radius:Int) extends Shape
case class Rectangle(width:Int, height:Int) extends Shape

def area(shape:Shape):Double = shape match {
       case Circle(radius) => 3.14*radius*radius
       case Rectangle(width, height) => width*height
}

The code above  does pattern matching on of input parameter type shape:Shape. In this case it is likely to use tuples to represent data in Rectangle and Circle classes.
Tuple2[String, Int]("circle", radius)
Tuple3[String, Int, Int]("rectangle", width, height)
So finally I want to write a code which does pattern matching on tuple. Here's how it is done with erlang

area({rect,Width,Height})->Width*Height;
area({circle,Radius})->3.14*Radius*Radius.


Is it possible to have something close in scala?  To be specific I mean this


def area(shape:Tuple):Double = shape match {
       case ("circle", radius) => 3.14*radius*radius
       case ("rectangle", width, height) => width*height
}

use overloading - don't match if the compiler can do it for you:
def area(shape:Tuple2[String, Int]):Double = 3.14*shape._2*shape_2
def area(shape:Tuple3[String, Int, Int]):Double = shape._2*shape._3

alternatively

  def area(shape:Product):Double = shape match {
    case Tuple2("circle", radius:Double) => 3.14*radius*radius
    case Tuple3("rectangle", width:Double, height:Double) => width*height
  }

    val circle:Tuple2[String, Int]=("circle", 10)
    val rect:Tuple3[String, Int, Int]=("rectangle", 5, 6)
    Console.println (area(circle))
    Console.println (area(rect))
    Console.println (area(("rectangle",3,2)))

but this is very fragile because of the type you have to define for radius, width and height

Re: pattern matching on tuples

by Robin Message :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

I think, for Scala, your first solution is the correct one. A tuple of 2
elements does not have the same type as a tuple of 3 elements, so you
have to go via Product. What's wrong with the code you posted to start
with, using case classes?

Robin

> On Jan 10, 2008 4:33 PM, Nazar Stasiv <nstasiv@...> wrote:
>         abstract class Shape
>         case class Circle(radius:Int) extends Shape
>         case class Rectangle(width:Int, height:Int) extends Shape
>        
>         def area(shape:Shape):Double = shape match {
>                case Circle(radius) => 3.14*radius*radius
>                case Rectangle(width, height) => width*height
>         }
>        

>
>   def area(shape:Product):Double = shape match {
>     case Tuple2("circle", radius:Double) => 3.14*radius*radius
>     case Tuple3("rectangle", width:Double, height:Double) =>
> width*height
>   }


Re: pattern matching on tuples

by Fredrik Roos :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

On Jan 10, 2008 4:55 PM, Carsten Saager <csaager@...> wrote:

>
>
>
>
> On Jan 10, 2008 4:33 PM, Nazar Stasiv <nstasiv@...> wrote:
> > Hello,
> >
> > abstract class Shape
> > case class Circle(radius:Int) extends Shape
> > case class Rectangle(width:Int, height:Int) extends Shape
> >
> > def area(shape:Shape):Double = shape match {
> >        case Circle(radius) => 3.14*radius*radius
> >        case Rectangle(width, height) => width*height
> > }
> >
> > The code above  does pattern matching on of input parameter type
> shape:Shape. In this case it is likely to use tuples to represent data in
> Rectangle and Circle classes.
> > Tuple2[String, Int]("circle", radius)
> > Tuple3[String, Int, Int]("rectangle", width, height)
> > So finally I want to write a code which does pattern matching on tuple.
> Here's how it is done with erlang
> >
> > area({rect,Width,Height})->Width*Height;
> > area({circle,Radius})->3.14*Radius*Radius.
> >
> >
> > Is it possible to have something close in scala?  To be specific I mean
> this
> >
> >
> > def area(shape:Tuple):Double = shape match {
> >        case ("circle", radius) => 3.14*radius*radius
> >        case ("rectangle", width, height) => width*height
> > }
> >
> >
> use overloading - don't match if the compiler can do it for you:
> def area(shape:Tuple2[String, Int]):Double = 3.14*shape._2*shape_2
>  def area(shape:Tuple3[String, Int, Int]):Double = shape._2*shape._3
>
> alternatively
>
>   def area(shape:Product):Double = shape match {
>      case Tuple2("circle", radius:Double) => 3.14*radius*radius
>      case Tuple3("rectangle", width:Double, height:Double) => width*height
>   }
>
>     val circle:Tuple2[String, Int]=("circle", 10)
>      val rect:Tuple3[String, Int, Int]=("rectangle", 5, 6)
>     Console.println (area(circle))
>      Console.println (area(rect))
>     Console.println (area(("rectangle",3,2)))
>
> but this is very fragile because of the type you have to define for radius,
> width and height

Tuples can be created and matched with simple parenthesis, like this:

("foo", 42) match { case (s : String, i : Int) => println(s + ", " + i) }

No need to use the TupleX constructors.

/f