I am trying to achieve the example shown in Martin Odersky's CourseRa Scala course to try and display expressions holding Sums/Prods using appropriate brackets. I came up with the below solution:
package expressions
trait Expr {
def eval : Int = {
this match {
case Number(n) => n
case Sum(e1,e2) => e1.eval + e2.eval
}
}
//def show( exp : Expr) : String
}
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(x:Char) extends Expr
object testExpr {
def show(exp : Expr) : String = {
exp match {
case Number(x) => x.toString()
case Sum(e1, e2) => show(e1) + "+" + show(e2)
case Prod(e1,e2) =>
val st1 = e1 match {
case Sum(a,b) => "(" + show(Sum(a,b)) + ")"
case _ => show(e1)
}
val st2 = e2 match {
case Sum(a,b) => "(" + show(Sum(a,b)) + ")"
case _ => show(e2)
}
st1 + "*" + st2
case Var(x) => x.toString
}
}
}
object test extends App{
println(testExpr.show(Sum(Number(1),Number(2))))
println(Sum(Number(1),Number(3)).eval)
println(testExpr.show(Sum(Number(2),Prod(Number(10),Var('x')))))
println(testExpr.show(Sum(Prod(Number(2),Var('x')),Var('y'))))
println(testExpr.show(Prod(Sum(Number(2),Var('x')),Var('y'))))
println(testExpr.show(Prod(Sum(Number(2),Var('x')),Sum(Number(3),Var('y')))))
}
The way I am deciding on putting the brackets is definitely not the best solution. Can anyone suggest a better solution to achieve the same.
Thanks and Regards, Paromita
Somewhat similar to ParoTech's and Val's, only slightly DRYer:
def show(e: Expr): String = {
def paren(e:Expr) = {
e match {
case Sum(_, _) => "(" + show(e) + ")"
case _ => show(e)
}
}
e match {
case Number(n) => n.toString
case Var(s) => s
case Sum(e1, e2) => show(e1) + " + " + show(e2)
case Prod(e1, e2) => paren(e1) + " * " + paren(e2)
}
}
you were pretty close actually. the code i've come up with is as follows:
case Variable(name) => name
case Product(e1, e2) => "%s * %s".format(
e1 match {
case Sum(_, _) => "(%s)".format(show(e1))
case _ => show(e1)
},
e2 match {
case Sum(_, _) => "(%s)".format(show(e2))
case _ => show(e2)
}
)
which would be further rewritten using tuple matching as
case Product(e1, e2) =>
val format = (e1, e2) match {
case (Sum(_, _), _) => "(%s) * %s"
case (_, Sum(_, _)) => "%s * (%s)"
case (_, _) => "%s * %s"
}
format.format(show(e1), show(e2))
I guess that supposed solution is to prefix
case Prod(l, r) => show(l) + "*" + show(r)
with
case Prod(Sum(sl, sr), r) => "(" + show(sl) + " + " + show(sr) + ")" + "*" + show(r)
as demonstrated here https://github.com/glebd/scala-course/blob/master/workspace/hello-project/src/week4/exprs.sc
The resulting code is
def show(e: Expr): String = e match {
case Number(n) => n.toString
case Var(v) => v
case Prod(Sum(e1, e2), Sum(e3, e4)) => "(" + show(e1) + "+" + show(e2) + ")*(" + show(e3) + "+" + show(e4) + ")"
case Prod(Sum(e1, e2), e3) => "(" + show(e1) + "+" + show(e2) + ")*" + show(e3)
case Prod(e1, Sum(e2, e3)) => show(e1) + "*(" + show(e2) + "+" + show(e3) + ")"
case Sum(e1, e2) => show(e1) + "+" + show(e2)
case Prod(e1, e2) => show(e1) + "*" + show(e2)
}
I have no idea what Krupennik's solution is supposed to do. Oderski did not demonstrate constructions like that. But this solution sheds some light on what Krupennik is doing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With