0

How can I convert a string in Scala into a corresponding operator? Given two integers and the string "+" I want the result of adding these two integers.

3 Answers 3

5

The last question is very simple:

def applyOperator(x: Int, y: Int, operator: String) = operator match {
  case "+" => x + y
  case "-" => x - y
  ...
}

You could try using Twitter's Eval library or reflection, but I wouldn't recommend it given the simpler solution.

For the first question: operators themselves aren't values, so you can't "convert a string into an operator". But you can come close: convert a string into a function which will add (or subtract, etc.) its arguments:

def stringToOperator(operator: String): (Int, Int) => Int = operator match {
  case "+" => _ + _
  case "-" => _ - _
  ...
}

You can even generalize it a bit to work not just on integers:

def stringToOperator[A: Numeric](operator: String): (A, A) => A = operator match { ... }

(This also applies to the first answer in the obvious way.)

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

2 Comments

Please can you add some explanaiton for the first code. lonely code doesn't say anything.
I've expanded the answer a bit.
1

This one

case class Evaluatee(v1: Int, operator: String, v2: Int)

object Evaluator {
  def raw(s: String)(v1: Int, v2: Int) = s match {
      case "+" => (v1 + v2)
      case "-" => (v1 - v2)
      case "*" => (v1 * v2)
      case "/" => (v1 / v2)
  }

  def evaluate(evaluatee: Evaluatee) =
    raw(evaluatee.operator)(evaluatee.v1, evaluatee.v2)
}

accomplishes this tests:

  test("1+1=2"){
    assert(Evaluator.evaluate(Evaluatee(1, "+", 1)) == 2)
  }
  test("2-1=1"){
    assert(Evaluator.evaluate(Evaluatee(2, "-", 1)) == 1)
  }
  test("1+1=2 raw"){
    assert(Evaluator.raw("+")(1,1) == 2)
  }

Comments

0

We cannot just do something like 1 "+" 2 because I think the biggest feature of scala to can make an own DSL is the apply method but I can not just calling it with nothing, I'm pretty sure we always need to use () or {} for example List(1) we can't do List 1 but we can List{1}.

But try this maybe could work for you

case class NumOp (num1:Int){
        def apply(op:String)(num2:Int):Int = {
                        op match {
                                case "+" => num1+num2
                                case "-" => num1-num2
                                case _ => 0
                        }
        }
}

object ConvertsNumOp{
        implicit def convert(a:Int):NumOp= NumOp(a)
}


import ConvertsNumOp._

scala> 2 ("-") (1)
res0: Int = 1

scala> 4 ("-") (2)
res1: Int = 2

scala> 4 ("+") (2)
res2: Int = 6
scala> 4 ("-") (2) ("+") (1) ("-") (8)
res0: Int = -5

You can do things dynamically so maybe could works.

EDITED:

Here is another version of NumOp maybe cleanest

case class NumOp(num1:Int) {
        def apply(op:String):Int => Int = {
                        op match {
                                case "+" => num1.+_
                                case "-" => num1.-_
                                case _ =>  throw new NotImplementedError("Operator not implemented")
                        }
        }
}

Using it dynamically

val numList = List(1,2,3,4,5,6,7,8,9,10);
val optList = List("+","-");
var retVal = for{ a <- numList; op <- optList } 
                      yield (a)(op)(a)

Comments

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.