This page is no longer maintained — Please continue to the home page at www.scala-lang.org

matching case classes with type parameters?

2 replies
Swade Leather
Joined: 2009-01-31,
User offline. Last seen 42 years 45 weeks ago.

I have a newbie question that perhaps someone can help me with. I'm
trying to have a base class with a type parameter and a pattern match:

abstract class X[T](var a : T)
{
// some type independent code (omitted)...

// type dependent
def field2val(field : String)
{
this match
{
case floatX(_) => a = field.toFloat;
case intX(_) => a = field.toInt;
}
}
}

case class floatX(a : Float) extends X[Float](a);
case class intX(a : Int) extends X[Int](a);

this leads to compile time errors with constructor errors and type
errors for each case:

test.scala:7: error: constructor cannot be instantiated to expected type;
found : floatX
required: X[T]
case floatX(_) => a = field.toFloat;
^
test.scala:7: error: type mismatch;
found : Float
required: T
case floatX(_) => a = field.toFloat;
...

Is there a more "correct" way to handle this? Basically, I want type
specialization for some small set of methods, but most are type
independent/generic.

thanks

Jens Alfke
Joined: 2009-01-30,
User offline. Last seen 42 years 45 weeks ago.
Re: matching case classes with type parameters?

Use regular OOP. Leave field2val abstract and implement it in each
concrete subclass.

Using matching for this is like swatting flies with a sledgehammer :-)

--Jens [via iPhone]

On Jan 31, 2009, at 9:07 AM, Swade Leather wrote:

> I have a newbie question that perhaps someone can help me with. I'm
> trying to have a base class with a type parameter and a pattern match:
>
> abstract class X[T](var a : T)
> {
> // some type independent code (omitted)...
>
> // type dependent
> def field2val(field : String)
> {
> this match
> {
> case floatX(_) => a = field.toFloat;
> case intX(_) => a = field.toInt;
> }
> }
> }
>
> case class floatX(a : Float) extends X[Float](a);
> case class intX(a : Int) extends X[Int](a);
>
> this leads to compile time errors with constructor errors and type
> errors for each case:
>
> test.scala:7: error: constructor cannot be instantiated to expected
> type;
> found : floatX
> required: X[T]
> case floatX(_) => a = field.toFloat;
> ^
> test.scala:7: error: type mismatch;
> found : Float
> required: T
> case floatX(_) => a = field.toFloat;
> ...
>
> Is there a more "correct" way to handle this? Basically, I want type
> specialization for some small set of methods, but most are type
> independent/generic.
>
> thanks

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: matching case classes with type parameters?
What you are trying to do is pretty crazy, but not impossible.

abstract class X[T](var a : T)
{
  def field2val(field : String) : Any = {
    val self : AnyRef = this
    
    self match {
      case selff: floatX => selff.a = field.toFloat
      case selfi: intX => selfi.a = field.toInt
    }
  }
}

case class floatX(param : Float) extends X[Float](param)
case class intX(param : Int) extends X[Int](param)

The question is: why not use abstract methods and overriding? You haven't sealed the base class X, so I can write arbitrary subclasses that wont' be caught by the match.

On Sat, Jan 31, 2009 at 9:07 AM, Swade Leather <swadenator [at] gmail [dot] com> wrote:
I have a newbie question that perhaps someone can help me with. I'm
trying to have a base class with a type parameter and a pattern match:

abstract class X[T](var a : T)
{
 // some type independent code (omitted)...

 // type dependent
 def field2val(field : String)
 {
   this match
   {
     case floatX(_) => a = field.toFloat;
     case intX(_) => a = field.toInt;
   }
 }
}

case class floatX(a : Float) extends X[Float](a);
case class intX(a : Int) extends X[Int](a);

this leads to compile time errors with constructor errors and type
errors for each case:

test.scala:7: error: constructor cannot be instantiated to expected type;
 found   : floatX
 required: X[T]
     case floatX(_) => a = field.toFloat;
          ^
test.scala:7: error: type mismatch;
 found   : Float
 required: T
     case floatX(_) => a = field.toFloat;
 ...

Is there a more "correct" way to handle this?  Basically, I want type
specialization for some small set of methods, but most are type
independent/generic.

thanks

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland