简体   繁体   中英

Assign value to variable in Scala Parser

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 !!

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 MatchError s whenever an unassigned variable is used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM