2014-10-04 54 views
6

在不同的Lisp,有可能爲我創造的一系列功能,就好像他們剛剛過正常值:如何在Scala中定義相同元素的函數列表?

(def ops [+ - * /]) 

,我可以再遍歷,再次,好像他們只是正常值:

(doseq [op ops] // (doseq (op ops) is like for (op <- ops) in scala 
    (println (op 1 2 3 4))) 

現在,我已經試過Scala中的幾件事情,他們都失敗:

scala> List(+, -, *, /) 
<console>:1: error: illegal start of simple expression 
     List(+, -, *, /) 
      ^

scala> List[Double => Double](+, -, *, /) 
<console>:1: error: illegal start of simple expression 
     List[Double => Double](+, -, *, /) 
          ^

scala> List[Double => Double](+_, -_, *_, /_) 
<console>:8: error: not found: value * 
       List[Double => Double](+_, -_, *_, /_) 
              ^
<console>:8: error: not found: value/
       List[Double => Double](+_, -_, *_, /_) 
               ^

那麼什麼是定義列表的正確方法Scala中的函數/操作符?

+0

下面有很好的答案,但是,正如你所看到的,你可以在這樣的方式只定義*同類型化*功能。如果你想存儲不同類型的函數,你必須使用* heterogeneous *結構(例如列表)。 – DaunnC 2014-10-04 08:32:46

+0

@DaunnC你會介意在這個問題的另一個答案中使用*使用異構結構*嗎?我會很感激。 – 2014-10-06 08:19:09

回答

11

問題是這些函數是二元運算符,即它們取兩個操作數並返回一個。所以,你必須使用:

List[(Double, Double) => Double](_ + _, _ - _, _ * _, _/_) 
1

在Scala中,最看重級運營商實際上是一元的實例方法(也許都是,不知道是否有counterexmaples)。因此,當你談論增加兩個Double類型的值時,你確實是指a method第一個將第二個值作爲參數的值。熟悉的中綴操作符語法is just sugar。換句話說,

scala> 5.7 + 6.3 
res0: Double = 12.0 

真的只是一個不錯的簡寫:

scala> 5.7.+(6.3) 
res1: Double = 12.0 

As @bluenote10 already mentioned,你可以通過創建取兩者的第一個實例和其作爲參數和返回操作數匿名函數捕獲這些運營商該+方法的結果:

scala> (lhs: Double, rhs: Double) => lhs + rhs 
res2: (Double, Double) => Double = <function2> 

或如@ bluenote10的示例中,如果類型可以在一個列表中被推斷(例如用t YPE提供),您可以用最好的下劃線語法:

scala> val doublePlus: (Double, Double) => Double = _ + _ 
doublePlus: (Double, Double) => Double = <function2> 
相關問題