2014-10-01 108 views
1

我嘗試學習咖喱功能在Scala中, 看到代碼斯卡拉咖喱功能

def isEven(v: Int): Boolean = v % 2 == 0 

    def evens(numbers: List[Int])(even: Int => Unit) { 
    for (number <- numbers; if isEven(number)) { 
     even(number) 
    } 
    } 

    val my = List.range(1, 100) 

    evens(my){println(_)} // works fine and prints the even numbers as expected 

    val recurse = evens(my) { yield _ } //compilation error 

我想獲得的結果爲產量的積累,但我不能罰款怎麼辦,在斯卡拉文檔或任何示例。 有什麼想法?

+1

我不認爲你可以從'for'部分分開'yield',也不是我能想到的任何可能的使用情況對於這一點,你必須在'evens'回報'Unit',又該'產量「呢? – 2014-10-01 19:58:10

+0

是的,「收益......」本身既不是陳述也不是表達。它只作爲'for ... yield ...'表達式的一部分存在。 – 2014-10-01 20:36:59

回答

4

你不能抽象的過度兩種形式for用法。其中一個脫到foreach,另一個脫到map和(可能)flatMap;返回類型也不同。

你可以寫兩個函數,或者你可以寫一個通用的方法,而忽略了返回值:如果您想要列表後面不變您使用identity功能

def evens[A](numbers: List[Int])(even: Int => A): List[A] = { 
    for (number <- numbers if (number % 2) == 0) yield even(number) 
} 

現在:

val e = evens(my)(identity) 
val e = evens(my)(x => x) // Equivalent 

如果您想做點什麼,您會忽略返回值:

evens(my)(println) 
+0

是的,它適用於我,但我仍然不明白這個伎倆,爲什麼它不能更優雅地定義。 – 2014-10-02 18:23:33

+0

@moshebeeri - 嗯,我不確定_which_部分你不明白,所以我可以建議的是要更熟悉斯卡拉。但至於爲什麼它不能被更優雅地定義,它只是關於'for'的構想。 Scala並非只是在做文本替換,所以你不能混合隨機部分的語法 - 例如。你不能'def foo =(_ bar = 5); foo(def)'創建'def bar = 5'。人們可以在語言設計中做出不同的決定來允許(取決於細節,最終得到更像C宏或Lisp的東西)。 – 2014-10-02 18:31:23

+0

考慮到這一代碼 DEF找齊(數字:列表[INT])(甚至:INT =>單元){對於 (數< - 數;如果ISEVEN(編號)){ 偶數(號碼) } } val f = evens(my)_ 爲什麼我可以調用函數f.foreach {println(_)} – 2014-10-03 16:22:31

0

個斯卡拉咖喱功能不被拘留與產量作爲我在我的問題, 爲目的,沒有必要使用咖喱的功能,就好象你根本CA以下嘗試:

def evens(numbers: List[Int]) : List[Int] = { 
    for (number <- numbers if (number % 2) == 0) yield number 
    } 

和然後:

val my = List.range(1, 100) 
    evens(my).foreach(f => println(f)) 

感謝@RexKerr他的解決方案說明如何利用泛型和咖喱的功能,產生並返回結果咖喱。