将函数传递给泛型函数

时间:2016-02-24 19:18:27

标签: scala generics

我有以下代码,我想抽象其他类型:

val users = Set[User](new User(1, "tyler"), new User(2, "phil"), new User(3, "quan"))
val groups = Set[Group](new Group(1, 10, 1), new Group(2, 20, 3))


def myFind(user: User)(implicit g: Group): Boolean = {
     user.id == g.adminID
}

val combined = groups.map(implicit g => {
    val admin = users.find(myFind)

    // Do something with relation
    g.toString + " " + admin.toString
})

println(combined)

我想做的是把它变成一个功能。到目前为止我所拥有的是:

def myFunc[A, B](s1: Set[A], s2: Set[B], f: (B) => Boolean): Set[String] = {
    s1.map(implicit t1 => {
        val rel = s2.find(f)
        t1.toString + " " + rel.to
    })
}

myFunc(users, groups, myFind)

有两个编译错误:

Could not find implicit value for parameter g: Sets.Group
myFunc(users, groups, myFind)
               ^

并且

Not enough arguments for method myFind: (implicit g: Sets.Group)Boolean.
Unspecified value parameter g.
myFunc(users, groups, myFind)
               ^

编辑:完整代码:

case class User(id: Int, name: String)
case class Group(id: Int, membersCount: Int, adminID: Int)

object Playground {

    def main(args: Array[String]) {

        val users = Set[User](new User(1, "tyler"), new User(2, "phil"), new User(3, "quan"))
        val groups = Set[Group](new Group(1, 10, 1), new Group(2, 20, 3))


        def myFind(user: User)(implicit g: Group): Boolean = {
            user.id == g.adminID
        }

        val combined = groups.map(implicit g => {
            val admin = users.find(myFind)

            // Do something with relation
            g.toString + " " + admin.toString
        })

        println(combined)

        myJoin(users, groups, myFind)

    }

    def myJoin[A, B](s1: Set[A], s2: Set[B], f: (B) => Boolean): Set[String] = {
        s1.map(implicit t1 => {
            val rel = s2.find(f)
            t1.toString + " " + rel.to
        })
    }
}

1 个答案:

答案 0 :(得分:2)

问题在于lgammamyFunc调用s2.find(f)时,没有f采用任何隐含参数的信息。而且你不能在函数参数的类型签名中表达这种信息。

我相信,您最好的选择是myFuncABBoolean(A, B) => Boolean或{{1} }})。

例如:

A => B => Boolean

然后,对于def myFunc[A, B](s1: Set[A], s2: Set[B], f: A => B => Boolean): Set[String] = s1.map { t1 => val rel = s2.find(f(t1)) t1.toString + " " + rel.to } 的定义,您可以通过以下方式之一将myFunc传递给它:

myFind

或者

myFunc(users, groups, (u: User) => { implicit g: Group => myFind(u)})

或者定义一个没有隐式参数的函数并直接传递它:

myFunc(users, groups, (u: User) => (g: Group) => myFind(u)(g))

或者,如果您有两个参数的函数,则可以使用def myFind2(user: User)(g: Group): Boolean = user.id == g.adminID myFunc(users, groups, myFind2) 方法将其传递给myFunc

curried