2013-01-09 99 views
2

我是新來scala和函數式編程。我正在嘗試通常的初學者應用程序和腳本(顯然使用了一些過度技術)如何讓此代碼更加功能

反正我有一個計算器的代碼,它需要參數和一個開關來指定要在參數上使用的操作。

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) 
    } 
} 

id想要找到更好的方法就像去除try catch語句一樣。

構建此應用程序的更好方法將非常受歡迎。

回答

4

這個怎麼樣?

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) 
    } 
} 
+0

相當優雅的做事方式!由於沒有添加新的_val_或_var_,因此也更加高效。感謝** om-nom-nom ** – korefn

+1

可能希望編譯'parseArguments(args,「」)'到'parseArguments(args.toList,「」「)'在2.9.2中不能編譯,因爲這個轉換似乎不是隱含的。 – korefn

+0

@ korefn是的,在我的腦海裏有這個想法,但是當我寫代碼的時候不知何故錯過了它。 –