0

i have a question about the Parser in Scala. I'll just post the important part here so that there would not be too much codes. For the eval Function:

def eval(t: Term): Double = t match {
    case Addition(l, r) => eval(l) + eval(r)
    case Multiplication(l, r) => eval(l) * eval(r)
    case Numeric(i) => i
    case Variable("X") => 3
    }

And the calculate function:

def calculate(arg: String): Double = {
    return eval(parseAll(term, arg).get)
  }

now i should overload the function "calculate" so that it takes an extra Parameter tup : (String, Double) and assign the value for this String. For example ("Y",2) then Y = 2 in the Parser. And then calculate the parser. But i don't know how to assign the value for this String. I had a stupid idea and tried this but it didn't work.

def calculate(arg: String, tup : (String, Double)) : Double = {
    tup match {
      case (a,b) => {
        def eval(t : Term): Double = t match {
          case Variable(a) => b
        }
        return eval(parseAll(term, arg).get)
      }
    }

can you guys pls help me out ? Thank you !!

1 Answer 1

4

You're almost there, you just need to tell the compiler that the a in your Variable pattern is actually the a from your (a, b) pattern. By default, what you do is called shadowing of the variable name a (in the scope of this pattern match, a is the value extracted in Variable, and the other a is forgotten).

What you want is something like

...
  case Variable(`a`) => b
...

or, if your expression gets a little more complicated, you should rather use a guard:

...
  case Variable(v) if v == a => b
...

EDIT However, now your eval function is not well defined. You need to put it all at once:

def eval(t: Term, varAssignement: (String, Double)): Double = t match {
  case Addition(l, r) => eval(l) + eval(r)
  case Multiplication(l, r) => eval(l) * eval(r)
  case Numeric(i) => i
  case Variable(a) if a == varAssignment._1 => varAssignment._2
}

Or, if you want to have multiple variables:

def eval(t: Term, assignments: Map[String, Double]): Double = t match {
  case Addition(l, r) => eval(l) + eval(r)
  case Multiplication(l, r) => eval(l) * eval(r)
  case Numeric(i) => i
  case Variable(a) if assignments.exists(a) => assignments(a)
}

Beware that you'll still get MatchErrors whenever an unassigned variable is used.

Sign up to request clarification or add additional context in comments.

2 Comments

i tried to use your method but when i call println(calculate("3+5*A",("A",2))), it throws exception like this Exception in thread "main" scala.MatchError: Addition(Numeric(3.0),Multiplication(Numeric(5.0),Variable(A))) so i guess the value 2 was not assigned to "A". The error is in the eval function where i do the shadowing in my pattern match
Oh, right. Your eval only matched if you have a Variable(``a``), you'll probably need all the cases. I'll edit my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.