2014-10-01 104 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他的解决方案说明如何利用泛型和咖喱的功能,产生并返回结果咖喱。