Displaying nested arithmetic expressions as a string using Scala pattern matching I am learning the concepts of pattern matching in Scala. Following is an exercise for the same. The task is to define a show function that outputs an expression as a String. Following are the definitions involved:

object Test {
  trait Expr
  case class Number(n: Int) extends Expr
  case class Sum(e1: Expr, e2: Expr) extends Expr
  case class Prod(e1: Expr, e2: Expr) extends Expr
  case class Var(name: String) extends Expr

  def nestOperations(e1: Expr, e2: Expr): String = {
    val l = e1 match {
      case Number(n) =&gt; n.toString
      case Prod(x, y) =&gt; nestOperations(x, y)
      case Var(s) =&gt; s
      case Sum(x, y) =&gt; "(" + show(x) + " + " + show(y) + ")"
    }
    val r = e2 match {
      case Number(n) =&gt; n.toString
      case Prod(x, y) =&gt; nestOperations(x, y)
      case Var(s) =&gt; s
      case Sum(x, y) =&gt; "(" + show(x) + " + " + show(y) + ")"
    }
    l + " * " + r
  }

  def show(e: Expr): String = e match {
    case Number(n) =&gt; n.toString
    case Sum(e1, e2) =&gt; show(e1) + " + " + show(e2)`
    case Prod(e1, e2) =&gt; nestOperations(e1, e2)
    case Var(s) =&gt; s
  }
  show(Sum(Number(1), Number(2)))
  show(Sum(Prod(Number(2), Var("x")), Var("y")))
  show(Prod(Sum(Number(2), Var("x")), Var("y")))
}


The expectation is that:
show(Sum(Number(1), Number(2))) outputs 1 + 2
show(Sum(Prod(Number(2), Var("x")), Var("y"))) outputs 2 * x + y
show(Prod(Sum(Number(2), Var("x")), Var("y"))) outputs (2 + x) * y  

The program achieves all of the above. I want to know if the nestOperations method can be simplified? Looks like a lot of repetitive code in there.
You're right.  That repeated code in nestOperations() can be eliminated.

def nestOperations(es: Expr*): String =
  es.map {
    case Number(n) =&gt; n.toString
    case Prod(x, y) =&gt; nestOperations(x, y)
    case Var(s) =&gt; s
    case Sum(x, y) =&gt; "(" + show(x) + " + " + show(y) + ")"
  }.mkString(" * ")


But why stop there?  You can pull much the same stunt with show() and eliminate nestOperations() altogether.

def show(es: Expr*): String = es.map{
  case Number(n) =&gt; n.toString
  case Sum(e1, e2) =&gt; if (es.length &gt; 1) "(" + show(e1) + " + " + show(e2) + ")"
                      else show(e1) + " + " + show(e2)
  case Prod(e1, e2) =&gt; show(e1, e2)
  case Var(s) =&gt; s
}.mkString(" * ")