将部分函数调用collect作为对象的成员

时间:2015-04-11 09:40:16

标签: list scala

我正在使用一些返回Options的函数,但是我想用PartialFunctions替换它们以便在Scala中使用collect函数。详细地说,我试图通过以下方式在包含部分函数的对象列表上调用collect(和collectFirst):

class A(val bs : List[B]) {
    def getAll(i : Int): List[Int] = bs.map(_.foo(i))
}

class B(val y : Int) {
    val foo : PartialFunction[Int, Int] = {
        case x if x > y => y
    }
}

如果为bs中的所有值定义了函数foo,上面的代码将编译并执行我想要的操作。

val a = new A(List(new B(1), new B(2), new B(3)));
println(a.getAll(5))

打印"列表(1,2,3)和#34;但是如果没有为值定义foo,我当然会遇到错误。因此,我想用"收集"

替换它
def getAll(i : Int): List[Int] = bs.collect(_.foo(i))

在我的理解中,collect应该与map完全相同,但上面的代码仍然无法编译(我得到类型不匹配,因为foo无法解析)。在这种情况下,最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

collect期望接收部分函数(不是函数或lambda),它将集合的元素作为输入:PartialFunction[B, Int]。但是在这里你只想在另一个函数中调用你的PartialFunction[Int, Int],所以你甚至不能将PartialFunction传递给collect(你正在传递函数{{1} })。

没有(_.foo(i)): B => Int的解决方案(但仍然collect作为PartialFunction的成员):

B

def getAll(i : Int): List[Int] = bs.flatMap(_.foo.lift(i)) 将您的职能从lift升级到PartialFunction[Int, Int]

如果你真的想要Int => Option[Int]

collect

import Function._ def getAll(i : Int): List[Int] = bs.collect(unlift(_.foo.lift(i))) unlift缩减为B => Option[Int]

最丑陋的版本是PartialFunction[B, Int]

更好的解决方案是将您的部分功能移到collect{ case x if x.foo.isDefinedAt(i) => x.foo(i) }之外:

B