Как сделать этот код более функциональным

Я новичок в скале и функциональном программировании. Я пробую обычные приложения для начинающих и сценарии (очевидно, с использованием немного чрезмерной технологии)

В любом случае у меня есть этот код для калькулятора, который принимает аргументы и переключатель, чтобы диктовать операцию для использования в аргументах.

object Main {
    def main(args: Array[String]): Unit = {

        var calc = calculate( "" , _:List[Int])
        var values:List[Int] = List()

        if(args.size < 1) println("No arguments supplied") else{
            args collect {_ match{
                    case arg if arg.contains("-") => {
                            if(values.size>0){
                                calc(values)
                                values = List()}
                            calc = calculate( arg , _:List[Int])
                        }
                    case arg => {
                            try{
                                val value=arg.toInt
                                values = values ::: List(value)
                            }catch{case e:NumberFormatException=>println("\nError:Invalid argument:\""+arg+"\"\nCannot convert to Integer.\n")}
                    }
                }
            }
            calc(values)
        }
    }

    def sum(values:List[Int]) { println("The sum is:"+(values.foldLeft(0)((sum,value) => sum + value))) }

    def subtract(values:List[Int]) {
        val initial:Int = values(0)

        var total:Int = 0
        for(i <- 1 until values.size){
            total = total + values(i)
        }
        val diff:Int = initial - total
        println("The difference is:"+diff)
    }

    def calculate(operation:String,values:List[Int]) = operation match {
        case "-sum" => sum(values)
        case "-diff" => subtract(values)
        case _ => println("Default operation \"Sum\" will be applied");sum(values)
    }
}

Некоторые моменты, которые хотелось бы найти, если есть лучший способ сделать это, как удалить оператор try catch.

Лучший способ составить это приложение будет приветствоваться.

1 ответ

Решение

Как насчет этого?

object Main extends App {
    require(args.size > 0, "Please, supply more arguments")

    @annotation.tailrec
    def parseArguments(arguments: List[String], operation: String, values: List[Int]() = Nil) {
        if(values.nonEmpty) calculate(operation, values)
        arguments match {
            case op::unprocessed if op.startsWith("-") => parseArguments(unprocessed, op)
            case maybeNumber::unprocessed => {
                val newValues = try {
                    maybeNumber.toInt::values
                } catch {
                    case _: NumberFormatException => 
                        println("\nError:Invalid argument:\""+maybeNumber+"\"\nCannot convert to Integer.\n")
                        values
                }             
                parseArguments(unprocessed, operation, newValues)   
            }
            case Nil => //done processing, exiting
        }
    }

    parseArguments(args.toList, "")

    def diff(values:List[Int]) = {
        val initial::tail = values
        val total = tail.sum
        initial - total
    }

    def calculate(operation:String, values:List[Int]) = operation match {
        case "-sum"  => println("The sum is " + values.sum)
        case "-diff" => println("The difference is: " + diff(values))
        case _       => 
                        println("""Default operation "Sum" will be applied""")
                        sum(values)
    }
}
Другие вопросы по тегам