我正在尝试完成一个非常简单的练习 - 过滤功能:
def filter[A](x: List[A], f: A => Boolean): List[A] = {
for(item <- x){
if(f(item))
yield item
}
}
但是它没有编译,似乎f(item)返回与Boolean不同的东西,但我无法理解,为什么。为了检查它,我试图这样做:
var b = Boolean
b = f(item)
之后我得到一个错误“布尔类型的表达式不符合预期的类型Boolean.type”。但我不明白这个解释。
你能帮忙理解这里有什么问题吗?该函数被调用为:
val list = 1 :: 2 :: 3 :: 4:: 5 :: 6 :: Nil
val list2 = filter[Int](list, _ % 2 == 0)
根据language specification,for-comprehension的yield
子句不能在复合表达式中,例如在一对牙套里面。它必须是for-comprehension的返回表达式中最外层的单词。
蒂姆解释说,你的if
也必须在一个特定的地方充当过滤器。在该位置,它被称为保护子句(请参阅规范以查看确切的语法)。
谓词确实返回Boolean
但你的for
循环的语法是错误的。它应该是这样的:
def filter[A](x: List[A], f: A => Boolean): List[A] =
for (item <- x if f(item)) yield item
但这更好:
def filter[A](x: List[A], f: A => Boolean): List[A] =
x.filter(f)
您可能知道您可以直接使用List的filter
方法:
def filter[A](x: List[A], f: A => Boolean): List[A] = x.filter(f)
但是如果你想用for-comprehension实现你的filter
方法,你可以按如下方式实现
def filter[A](x: List[A], f: A => Boolean): List[A] = {
for {
item <- x
if (f(item))
} yield item
}