1

I am working with trees and lists of expressions (Exp, members removed for brevity).

sealed abstract class Exp
abstract class BinaryExp extends Exp
case class Add extends BinaryExp

Most of the time I use pattern matching to process a tree or list of expressions. But sometimes this is a bit tedious and I want to be able to write:

if (exp.isBinary) ...
//or 
exps.filter(_.isAdd) ...

But this would mean that I need to create all sorts of properties in Exp with an implementation like:

def isXXX = this.isInstanceOf[XXXExp]

My first attempt to make this generic does not work because of type erasure:

def is[T <: Exp] = this.isInstanceOf[T]

So I searched for a solution and found TypeTags:
http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html
Scala: What is a TypeTag and how do I use it?

Attempt with TypeTags does not work either:

sealed abstract class Exp {
  // Cannot use isInstanceOf because of type erasure.
  import reflect.runtime.universe._
  def is[T <: Exp: TypeTag] = typeOf[this.type] <:< typeOf[T]
  def as[T <: Exp] = asInstanceOf[T]
}

Is there a way in Scala to do this?

Community
  • 1
  • 1
Julian Lettner
  • 3,309
  • 7
  • 32
  • 49
  • Sounds like you need to write a macro for this. http://docs.scala-lang.org/overviews/macros/overview.html – Ashalynd Feb 25 '14 at 02:14
  • Can you give a use-case for when you want to use isXXX? It seems you want to do something different depending on the subclass, and that's the kind of thing inheritance and overriding were invented for... – The Archetypal Paul Feb 25 '14 at 08:36
  • ...and (amending @Paul's comment) polymorphism. – mikołak Feb 25 '14 at 11:59
  • And if you really need it, `def isXXX = this.isInstanceOf[XXXExp]` is not the way to go. Implement an abstract isXXX in Exp, then implement it to return `true` or `false` as appropriate in the subclasses. – The Archetypal Paul Feb 25 '14 at 12:41

1 Answers1

0

You can try Manifest (note that it is deprecated in 2.10).

  sealed abstract class Exp {
     def is[T <: Exp: Manifest] = implicitly[Manifest[T]].erasure.isInstance(this)  
     def as[T <: Exp] = asInstanceOf[T]
  }

Example: http://ideone.com/47Q5W3

chemikadze
  • 815
  • 4
  • 12