Scalaなんでかな case class

case classとclassの使い分けがいまいち分かりにくかったので、classとobjectキーワードを使ってcase classと同じようなものを作ってみた。

これで全て再現しているかは分からないが、case claseを使うと以下のものが自動的に実現されるので、それを再現した。

・toString で内容を表示
  case class:オブジェクトの内容が表示される
  class オブジェクトのアドレスが表示される

・==がオブジェクトの属性の値で比較判断される

・暗黙のVAL定義

・パターンマッチングのクラス名の直接表示 case BinOp("+", e, Number(0)) => e

・newが不要

こうしてソースを比較するとcase classは簡単だと実感できます。

                                                                • -

package sample

object Extractor {
abstract class Expr
class Var(val name: String) extends Expr{
override def equals(obj:Any) = obj match{
case o:Var => o.name == name
case _=> false
}
override def toString() = "Var("+name+")";
}
class Number(val num: int) extends Expr{
override def equals(obj:Any) = obj match{
case o:Number => o.num == num
case _=> false
}
override def toString() = "Number("+num+")";
}
class BinOp(val operator: String,val left: Expr,val right: Expr) extends Expr{
override def equals(obj:Any) = obj match{
case o:BinOp => o.operator == operator && o.left == left && o.right == right
case _=> false
}
override def toString() = "BinOp("+operator+","+left+","+right+")";
}
object Var extends Expr{
def apply(name: String) = new Var(name)
def unapply(exp:Var) = Some(exp.name)
};
object Number extends Expr{
def apply(num: int) = new Number(num)
def unapply(num:Number) = Some(num.num)
};
object BinOp extends Expr{
def apply(operator: String,left: Expr,right: Expr) = new BinOp(operator,left,right)
def unapply(bin:BinOp) = Some[(String,Expr,Expr)](bin.operator,bin.left,bin.right);
}
def simplifyTop(expr: Expr): Expr = expr match {
case BinOp("+", e, Number(0)) => e // Adding zero
case BinOp("*", e, Number(1)) => e // Multiplying by one
case _ => expr
}
def main(arg:Array[String]){
val v = Var("x")
val op = BinOp("+", v,Number(0))
println(v.name)
println(v == Var("x"))
println(op == BinOp("+", Var("x"),Number(0)))
println(op)
println(simplifyTop(op))
}
}

                                                                • -

package sample

object Case {
abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: int) extends Expr
case class BinOp(operator: String,left: Expr, right: Expr) extends Expr
def simplifyTop(expr: Expr): Expr = expr match {
case BinOp("+", e, Number(0)) => e // Adding zero
case BinOp("*", e, Number(1)) => e // Multiplying by one
case _ => expr
}
def main(arg:Array[String]){
val v = Var("x")
val op = BinOp("+", v,Number(0))
println(v.name)
println(v == Var("x"))
println(op == BinOp("+", Var("x"),Number(0)))
println(op)
println(simplifyTop(op))
}
}